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

package food.menu.v1;

public final class FoodMenu {
  private FoodMenu() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistryLite registry) {
  }

  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
    registerAllExtensions(
        (com.google.protobuf.ExtensionRegistryLite) registry);
  }
  /**
   * <pre>
   * Indicates a dietary restriction or guideline adhered to during
   * food preparation.
   * </pre>
   *
   * Protobuf enum {@code food.menu.v1.DietaryRestriction}
   */
  public enum DietaryRestriction
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Do not use. The dietary restriction is not explicitly specified.
     * </pre>
     *
     * <code>DIET_UNSPECIFIED = 0;</code>
     */
    DIET_UNSPECIFIED(0),
    /**
     * <code>DIET_DIABETIC = 1;</code>
     */
    DIET_DIABETIC(1),
    /**
     * <code>DIET_GLUTEN_FREE = 2;</code>
     */
    DIET_GLUTEN_FREE(2),
    /**
     * <code>DIET_HALAL = 3;</code>
     */
    DIET_HALAL(3),
    /**
     * <code>DIET_HINDU = 4;</code>
     */
    DIET_HINDU(4),
    /**
     * <code>DIET_KOSHER = 5;</code>
     */
    DIET_KOSHER(5),
    /**
     * <code>DIET_LOW_CALORIE = 6;</code>
     */
    DIET_LOW_CALORIE(6),
    /**
     * <code>DIET_LOW_FAT = 7;</code>
     */
    DIET_LOW_FAT(7),
    /**
     * <code>DIET_LOW_LACTOSE = 8;</code>
     */
    DIET_LOW_LACTOSE(8),
    /**
     * <code>DIET_LOW_SALT = 9;</code>
     */
    DIET_LOW_SALT(9),
    /**
     * <code>DIET_VEGAN = 10;</code>
     */
    DIET_VEGAN(10),
    /**
     * <code>DIET_VEGETARIAN = 11;</code>
     */
    DIET_VEGETARIAN(11),
    UNRECOGNIZED(-1),
    ;

    /**
     * <pre>
     * Do not use. The dietary restriction is not explicitly specified.
     * </pre>
     *
     * <code>DIET_UNSPECIFIED = 0;</code>
     */
    public static final int DIET_UNSPECIFIED_VALUE = 0;
    /**
     * <code>DIET_DIABETIC = 1;</code>
     */
    public static final int DIET_DIABETIC_VALUE = 1;
    /**
     * <code>DIET_GLUTEN_FREE = 2;</code>
     */
    public static final int DIET_GLUTEN_FREE_VALUE = 2;
    /**
     * <code>DIET_HALAL = 3;</code>
     */
    public static final int DIET_HALAL_VALUE = 3;
    /**
     * <code>DIET_HINDU = 4;</code>
     */
    public static final int DIET_HINDU_VALUE = 4;
    /**
     * <code>DIET_KOSHER = 5;</code>
     */
    public static final int DIET_KOSHER_VALUE = 5;
    /**
     * <code>DIET_LOW_CALORIE = 6;</code>
     */
    public static final int DIET_LOW_CALORIE_VALUE = 6;
    /**
     * <code>DIET_LOW_FAT = 7;</code>
     */
    public static final int DIET_LOW_FAT_VALUE = 7;
    /**
     * <code>DIET_LOW_LACTOSE = 8;</code>
     */
    public static final int DIET_LOW_LACTOSE_VALUE = 8;
    /**
     * <code>DIET_LOW_SALT = 9;</code>
     */
    public static final int DIET_LOW_SALT_VALUE = 9;
    /**
     * <code>DIET_VEGAN = 10;</code>
     */
    public static final int DIET_VEGAN_VALUE = 10;
    /**
     * <code>DIET_VEGETARIAN = 11;</code>
     */
    public static final int DIET_VEGETARIAN_VALUE = 11;


    public final int getNumber() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalArgumentException(
            "Can't get the number of an unknown enum value.");
      }
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static DietaryRestriction valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static DietaryRestriction forNumber(int value) {
      switch (value) {
        case 0: return DIET_UNSPECIFIED;
        case 1: return DIET_DIABETIC;
        case 2: return DIET_GLUTEN_FREE;
        case 3: return DIET_HALAL;
        case 4: return DIET_HINDU;
        case 5: return DIET_KOSHER;
        case 6: return DIET_LOW_CALORIE;
        case 7: return DIET_LOW_FAT;
        case 8: return DIET_LOW_LACTOSE;
        case 9: return DIET_LOW_SALT;
        case 10: return DIET_VEGAN;
        case 11: return DIET_VEGETARIAN;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<DietaryRestriction>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        DietaryRestriction> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<DietaryRestriction>() {
            public DietaryRestriction findValueByNumber(int number) {
              return DietaryRestriction.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalStateException(
            "Can't get the descriptor of an unrecognized enum value.");
      }
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.getDescriptor().getEnumTypes().get(0);
    }

    private static final DietaryRestriction[] VALUES = values();

    public static DietaryRestriction valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      if (desc.getIndex() == -1) {
        return UNRECOGNIZED;
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private DietaryRestriction(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:food.menu.v1.DietaryRestriction)
  }

  /**
   * <pre>
   * Allergen type derived from GS1: http://gs1.org/voc/AllergenTypeCode
   * </pre>
   *
   * Protobuf enum {@code food.menu.v1.AllergenTypeCode}
   */
  public enum AllergenTypeCode
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Do not use. The allergen type code is not explicitly specified.
     * </pre>
     *
     * <code>ALLERGEN_TYPE_CODE_UNSPECIFIED = 0;</code>
     */
    ALLERGEN_TYPE_CODE_UNSPECIFIED(0),
    /**
     * <code>ALLERGEN_TYPE_CODE_ALMONDS = 1;</code>
     */
    ALLERGEN_TYPE_CODE_ALMONDS(1),
    /**
     * <code>ALLERGEN_TYPE_CODE_ALPHA_ISOMETHYL_IONONE = 2;</code>
     */
    ALLERGEN_TYPE_CODE_ALPHA_ISOMETHYL_IONONE(2),
    /**
     * <code>ALLERGEN_TYPE_CODE_ALCOHOL = 3;</code>
     */
    ALLERGEN_TYPE_CODE_ALCOHOL(3),
    /**
     * <code>ALLERGEN_TYPE_CODE_AMYL_CINNAMAL = 4;</code>
     */
    ALLERGEN_TYPE_CODE_AMYL_CINNAMAL(4),
    /**
     * <code>ALLERGEN_TYPE_CODE_ANISE_ALCOHOL = 5;</code>
     */
    ALLERGEN_TYPE_CODE_ANISE_ALCOHOL(5),
    /**
     * <code>ALLERGEN_TYPE_CODE_BARLEY = 6;</code>
     */
    ALLERGEN_TYPE_CODE_BARLEY(6),
    /**
     * <code>ALLERGEN_TYPE_CODE_BENZYL_ALCOHOL = 7;</code>
     */
    ALLERGEN_TYPE_CODE_BENZYL_ALCOHOL(7),
    /**
     * <code>ALLERGEN_TYPE_CODE_BENZYL_BENZOATE = 8;</code>
     */
    ALLERGEN_TYPE_CODE_BENZYL_BENZOATE(8),
    /**
     * <code>ALLERGEN_TYPE_CODE_BENZYL_CINNAMATE = 9;</code>
     */
    ALLERGEN_TYPE_CODE_BENZYL_CINNAMATE(9),
    /**
     * <code>ALLERGEN_TYPE_CODE_BENZYL_SALICYLATE = 10;</code>
     */
    ALLERGEN_TYPE_CODE_BENZYL_SALICYLATE(10),
    /**
     * <code>ALLERGEN_TYPE_CODE_BRAZIL_NUTS = 11;</code>
     */
    ALLERGEN_TYPE_CODE_BRAZIL_NUTS(11),
    /**
     * <code>ALLERGEN_TYPE_CODE_BUTYLPHENYL_METHYLPROPIONATE = 12;</code>
     */
    ALLERGEN_TYPE_CODE_BUTYLPHENYL_METHYLPROPIONATE(12),
    /**
     * <code>ALLERGEN_TYPE_CODE_CARROTS = 13;</code>
     */
    ALLERGEN_TYPE_CODE_CARROTS(13),
    /**
     * <code>ALLERGEN_TYPE_CODE_CASHEW_NUTS = 14;</code>
     */
    ALLERGEN_TYPE_CODE_CASHEW_NUTS(14),
    /**
     * <code>ALLERGEN_TYPE_CODE_CELERY = 15;</code>
     */
    ALLERGEN_TYPE_CODE_CELERY(15),
    /**
     * <code>ALLERGEN_TYPE_CODE_CEREALS_CONTAINING_GLUTEN = 16;</code>
     */
    ALLERGEN_TYPE_CODE_CEREALS_CONTAINING_GLUTEN(16),
    /**
     * <code>ALLERGEN_TYPE_CODE_CINNAMAL = 17;</code>
     */
    ALLERGEN_TYPE_CODE_CINNAMAL(17),
    /**
     * <code>ALLERGEN_TYPE_CODE_CINNAMYL_ALCOHOL = 18;</code>
     */
    ALLERGEN_TYPE_CODE_CINNAMYL_ALCOHOL(18),
    /**
     * <code>ALLERGEN_TYPE_CODE_CITRAL = 19;</code>
     */
    ALLERGEN_TYPE_CODE_CITRAL(19),
    /**
     * <code>ALLERGEN_TYPE_CODE_CITRONELLOL = 20;</code>
     */
    ALLERGEN_TYPE_CODE_CITRONELLOL(20),
    /**
     * <code>ALLERGEN_TYPE_CODE_COCOA = 21;</code>
     */
    ALLERGEN_TYPE_CODE_COCOA(21),
    /**
     * <code>ALLERGEN_TYPE_CODE_CORIANDER = 22;</code>
     */
    ALLERGEN_TYPE_CODE_CORIANDER(22),
    /**
     * <code>ALLERGEN_TYPE_CODE_CORN = 23;</code>
     */
    ALLERGEN_TYPE_CODE_CORN(23),
    /**
     * <code>ALLERGEN_TYPE_CODE_COUMARIN = 24;</code>
     */
    ALLERGEN_TYPE_CODE_COUMARIN(24),
    /**
     * <code>ALLERGEN_TYPE_CODE_CRUSTACEANS = 25;</code>
     */
    ALLERGEN_TYPE_CODE_CRUSTACEANS(25),
    /**
     * <code>ALLERGEN_TYPE_CODE_EGGS = 26;</code>
     */
    ALLERGEN_TYPE_CODE_EGGS(26),
    /**
     * <code>ALLERGEN_TYPE_CODE_EUGENOL = 27;</code>
     */
    ALLERGEN_TYPE_CODE_EUGENOL(27),
    /**
     * <code>ALLERGEN_TYPE_CODE_EVERNIA_FURFURACEA = 28;</code>
     */
    ALLERGEN_TYPE_CODE_EVERNIA_FURFURACEA(28),
    /**
     * <code>ALLERGEN_TYPE_CODE_EVERNIA_PRUNASTRI = 29;</code>
     */
    ALLERGEN_TYPE_CODE_EVERNIA_PRUNASTRI(29),
    /**
     * <code>ALLERGEN_TYPE_CODE_FARNESOL = 30;</code>
     */
    ALLERGEN_TYPE_CODE_FARNESOL(30),
    /**
     * <code>ALLERGEN_TYPE_CODE_FISH = 31;</code>
     */
    ALLERGEN_TYPE_CODE_FISH(31),
    /**
     * <code>ALLERGEN_TYPE_CODE_GERANIOL = 32;</code>
     */
    ALLERGEN_TYPE_CODE_GERANIOL(32),
    /**
     * <code>ALLERGEN_TYPE_CODE_GLUTEN = 33;</code>
     */
    ALLERGEN_TYPE_CODE_GLUTEN(33),
    /**
     * <code>ALLERGEN_TYPE_CODE_HAZELNUTS = 34;</code>
     */
    ALLERGEN_TYPE_CODE_HAZELNUTS(34),
    /**
     * <code>ALLERGEN_TYPE_CODE_HEXYL_CINNAMAL = 35;</code>
     */
    ALLERGEN_TYPE_CODE_HEXYL_CINNAMAL(35),
    /**
     * <code>ALLERGEN_TYPE_CODE_HYDROXYCITRONELLAL = 36;</code>
     */
    ALLERGEN_TYPE_CODE_HYDROXYCITRONELLAL(36),
    /**
     * <code>ALLERGEN_TYPE_CODE_HYDROXYISOHEXYL_3_CYCLOHEXENE_CARBOXALDEHYDE_ISOEUGENOL_LIMONENE_LINAL = 37;</code>
     */
    ALLERGEN_TYPE_CODE_HYDROXYISOHEXYL_3_CYCLOHEXENE_CARBOXALDEHYDE_ISOEUGENOL_LIMONENE_LINAL(37),
    /**
     * <code>ALLERGEN_TYPE_CODE_KAMUT = 38;</code>
     */
    ALLERGEN_TYPE_CODE_KAMUT(38),
    /**
     * <code>ALLERGEN_TYPE_CODE_LACTOSE = 39;</code>
     */
    ALLERGEN_TYPE_CODE_LACTOSE(39),
    /**
     * <code>ALLERGEN_TYPE_CODE_LUPINE = 40;</code>
     */
    ALLERGEN_TYPE_CODE_LUPINE(40),
    /**
     * <code>ALLERGEN_TYPE_CODE_MACADAMIA_NUTS = 41;</code>
     */
    ALLERGEN_TYPE_CODE_MACADAMIA_NUTS(41),
    /**
     * <code>ALLERGEN_TYPE_CODE_METHYL_2_OCTYNOATE = 42;</code>
     */
    ALLERGEN_TYPE_CODE_METHYL_2_OCTYNOATE(42),
    /**
     * <code>ALLERGEN_TYPE_CODE_MILK = 43;</code>
     */
    ALLERGEN_TYPE_CODE_MILK(43),
    /**
     * <code>ALLERGEN_TYPE_CODE_MOLLUSCS = 44;</code>
     */
    ALLERGEN_TYPE_CODE_MOLLUSCS(44),
    /**
     * <code>ALLERGEN_TYPE_CODE_MUSTARD = 45;</code>
     */
    ALLERGEN_TYPE_CODE_MUSTARD(45),
    /**
     * <code>ALLERGEN_TYPE_CODE_NO_DECLARED_ALLERGENS = 46;</code>
     */
    ALLERGEN_TYPE_CODE_NO_DECLARED_ALLERGENS(46),
    /**
     * <code>ALLERGEN_TYPE_CODE_OAT = 47;</code>
     */
    ALLERGEN_TYPE_CODE_OAT(47),
    /**
     * <code>ALLERGEN_TYPE_CODE_PEANUTS = 48;</code>
     */
    ALLERGEN_TYPE_CODE_PEANUTS(48),
    /**
     * <code>ALLERGEN_TYPE_CODE_PEAS = 49;</code>
     */
    ALLERGEN_TYPE_CODE_PEAS(49),
    /**
     * <code>ALLERGEN_TYPE_CODE_PECAN_NUTS = 50;</code>
     */
    ALLERGEN_TYPE_CODE_PECAN_NUTS(50),
    /**
     * <code>ALLERGEN_TYPE_CODE_PISTACHIOS = 51;</code>
     */
    ALLERGEN_TYPE_CODE_PISTACHIOS(51),
    /**
     * <code>ALLERGEN_TYPE_CODE_POD_FRUITS = 52;</code>
     */
    ALLERGEN_TYPE_CODE_POD_FRUITS(52),
    /**
     * <code>ALLERGEN_TYPE_CODE_QUEENSLAND_NUTS = 53;</code>
     */
    ALLERGEN_TYPE_CODE_QUEENSLAND_NUTS(53),
    /**
     * <code>ALLERGEN_TYPE_CODE_RYE = 54;</code>
     */
    ALLERGEN_TYPE_CODE_RYE(54),
    /**
     * <code>ALLERGEN_TYPE_CODE_SESAME_SEEDS = 55;</code>
     */
    ALLERGEN_TYPE_CODE_SESAME_SEEDS(55),
    /**
     * <code>ALLERGEN_TYPE_CODE_SOYBEANS = 56;</code>
     */
    ALLERGEN_TYPE_CODE_SOYBEANS(56),
    /**
     * <code>ALLERGEN_TYPE_CODE_SPELT = 57;</code>
     */
    ALLERGEN_TYPE_CODE_SPELT(57),
    /**
     * <code>ALLERGEN_TYPE_CODE_SULPHUR_DIOXIDE = 58;</code>
     */
    ALLERGEN_TYPE_CODE_SULPHUR_DIOXIDE(58),
    /**
     * <code>ALLERGEN_TYPE_CODE_TREE_NUTS = 59;</code>
     */
    ALLERGEN_TYPE_CODE_TREE_NUTS(59),
    /**
     * <code>ALLERGEN_TYPE_CODE_TREE_NUT_TRACES = 60;</code>
     */
    ALLERGEN_TYPE_CODE_TREE_NUT_TRACES(60),
    /**
     * <code>ALLERGEN_TYPE_CODE_WALNUTS = 61;</code>
     */
    ALLERGEN_TYPE_CODE_WALNUTS(61),
    /**
     * <code>ALLERGEN_TYPE_CODE_WHEAT = 62;</code>
     */
    ALLERGEN_TYPE_CODE_WHEAT(62),
    UNRECOGNIZED(-1),
    ;

    /**
     * <pre>
     * Do not use. The allergen type code is not explicitly specified.
     * </pre>
     *
     * <code>ALLERGEN_TYPE_CODE_UNSPECIFIED = 0;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_UNSPECIFIED_VALUE = 0;
    /**
     * <code>ALLERGEN_TYPE_CODE_ALMONDS = 1;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_ALMONDS_VALUE = 1;
    /**
     * <code>ALLERGEN_TYPE_CODE_ALPHA_ISOMETHYL_IONONE = 2;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_ALPHA_ISOMETHYL_IONONE_VALUE = 2;
    /**
     * <code>ALLERGEN_TYPE_CODE_ALCOHOL = 3;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_ALCOHOL_VALUE = 3;
    /**
     * <code>ALLERGEN_TYPE_CODE_AMYL_CINNAMAL = 4;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_AMYL_CINNAMAL_VALUE = 4;
    /**
     * <code>ALLERGEN_TYPE_CODE_ANISE_ALCOHOL = 5;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_ANISE_ALCOHOL_VALUE = 5;
    /**
     * <code>ALLERGEN_TYPE_CODE_BARLEY = 6;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_BARLEY_VALUE = 6;
    /**
     * <code>ALLERGEN_TYPE_CODE_BENZYL_ALCOHOL = 7;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_BENZYL_ALCOHOL_VALUE = 7;
    /**
     * <code>ALLERGEN_TYPE_CODE_BENZYL_BENZOATE = 8;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_BENZYL_BENZOATE_VALUE = 8;
    /**
     * <code>ALLERGEN_TYPE_CODE_BENZYL_CINNAMATE = 9;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_BENZYL_CINNAMATE_VALUE = 9;
    /**
     * <code>ALLERGEN_TYPE_CODE_BENZYL_SALICYLATE = 10;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_BENZYL_SALICYLATE_VALUE = 10;
    /**
     * <code>ALLERGEN_TYPE_CODE_BRAZIL_NUTS = 11;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_BRAZIL_NUTS_VALUE = 11;
    /**
     * <code>ALLERGEN_TYPE_CODE_BUTYLPHENYL_METHYLPROPIONATE = 12;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_BUTYLPHENYL_METHYLPROPIONATE_VALUE = 12;
    /**
     * <code>ALLERGEN_TYPE_CODE_CARROTS = 13;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_CARROTS_VALUE = 13;
    /**
     * <code>ALLERGEN_TYPE_CODE_CASHEW_NUTS = 14;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_CASHEW_NUTS_VALUE = 14;
    /**
     * <code>ALLERGEN_TYPE_CODE_CELERY = 15;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_CELERY_VALUE = 15;
    /**
     * <code>ALLERGEN_TYPE_CODE_CEREALS_CONTAINING_GLUTEN = 16;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_CEREALS_CONTAINING_GLUTEN_VALUE = 16;
    /**
     * <code>ALLERGEN_TYPE_CODE_CINNAMAL = 17;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_CINNAMAL_VALUE = 17;
    /**
     * <code>ALLERGEN_TYPE_CODE_CINNAMYL_ALCOHOL = 18;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_CINNAMYL_ALCOHOL_VALUE = 18;
    /**
     * <code>ALLERGEN_TYPE_CODE_CITRAL = 19;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_CITRAL_VALUE = 19;
    /**
     * <code>ALLERGEN_TYPE_CODE_CITRONELLOL = 20;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_CITRONELLOL_VALUE = 20;
    /**
     * <code>ALLERGEN_TYPE_CODE_COCOA = 21;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_COCOA_VALUE = 21;
    /**
     * <code>ALLERGEN_TYPE_CODE_CORIANDER = 22;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_CORIANDER_VALUE = 22;
    /**
     * <code>ALLERGEN_TYPE_CODE_CORN = 23;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_CORN_VALUE = 23;
    /**
     * <code>ALLERGEN_TYPE_CODE_COUMARIN = 24;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_COUMARIN_VALUE = 24;
    /**
     * <code>ALLERGEN_TYPE_CODE_CRUSTACEANS = 25;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_CRUSTACEANS_VALUE = 25;
    /**
     * <code>ALLERGEN_TYPE_CODE_EGGS = 26;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_EGGS_VALUE = 26;
    /**
     * <code>ALLERGEN_TYPE_CODE_EUGENOL = 27;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_EUGENOL_VALUE = 27;
    /**
     * <code>ALLERGEN_TYPE_CODE_EVERNIA_FURFURACEA = 28;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_EVERNIA_FURFURACEA_VALUE = 28;
    /**
     * <code>ALLERGEN_TYPE_CODE_EVERNIA_PRUNASTRI = 29;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_EVERNIA_PRUNASTRI_VALUE = 29;
    /**
     * <code>ALLERGEN_TYPE_CODE_FARNESOL = 30;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_FARNESOL_VALUE = 30;
    /**
     * <code>ALLERGEN_TYPE_CODE_FISH = 31;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_FISH_VALUE = 31;
    /**
     * <code>ALLERGEN_TYPE_CODE_GERANIOL = 32;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_GERANIOL_VALUE = 32;
    /**
     * <code>ALLERGEN_TYPE_CODE_GLUTEN = 33;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_GLUTEN_VALUE = 33;
    /**
     * <code>ALLERGEN_TYPE_CODE_HAZELNUTS = 34;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_HAZELNUTS_VALUE = 34;
    /**
     * <code>ALLERGEN_TYPE_CODE_HEXYL_CINNAMAL = 35;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_HEXYL_CINNAMAL_VALUE = 35;
    /**
     * <code>ALLERGEN_TYPE_CODE_HYDROXYCITRONELLAL = 36;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_HYDROXYCITRONELLAL_VALUE = 36;
    /**
     * <code>ALLERGEN_TYPE_CODE_HYDROXYISOHEXYL_3_CYCLOHEXENE_CARBOXALDEHYDE_ISOEUGENOL_LIMONENE_LINAL = 37;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_HYDROXYISOHEXYL_3_CYCLOHEXENE_CARBOXALDEHYDE_ISOEUGENOL_LIMONENE_LINAL_VALUE = 37;
    /**
     * <code>ALLERGEN_TYPE_CODE_KAMUT = 38;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_KAMUT_VALUE = 38;
    /**
     * <code>ALLERGEN_TYPE_CODE_LACTOSE = 39;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_LACTOSE_VALUE = 39;
    /**
     * <code>ALLERGEN_TYPE_CODE_LUPINE = 40;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_LUPINE_VALUE = 40;
    /**
     * <code>ALLERGEN_TYPE_CODE_MACADAMIA_NUTS = 41;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_MACADAMIA_NUTS_VALUE = 41;
    /**
     * <code>ALLERGEN_TYPE_CODE_METHYL_2_OCTYNOATE = 42;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_METHYL_2_OCTYNOATE_VALUE = 42;
    /**
     * <code>ALLERGEN_TYPE_CODE_MILK = 43;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_MILK_VALUE = 43;
    /**
     * <code>ALLERGEN_TYPE_CODE_MOLLUSCS = 44;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_MOLLUSCS_VALUE = 44;
    /**
     * <code>ALLERGEN_TYPE_CODE_MUSTARD = 45;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_MUSTARD_VALUE = 45;
    /**
     * <code>ALLERGEN_TYPE_CODE_NO_DECLARED_ALLERGENS = 46;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_NO_DECLARED_ALLERGENS_VALUE = 46;
    /**
     * <code>ALLERGEN_TYPE_CODE_OAT = 47;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_OAT_VALUE = 47;
    /**
     * <code>ALLERGEN_TYPE_CODE_PEANUTS = 48;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_PEANUTS_VALUE = 48;
    /**
     * <code>ALLERGEN_TYPE_CODE_PEAS = 49;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_PEAS_VALUE = 49;
    /**
     * <code>ALLERGEN_TYPE_CODE_PECAN_NUTS = 50;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_PECAN_NUTS_VALUE = 50;
    /**
     * <code>ALLERGEN_TYPE_CODE_PISTACHIOS = 51;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_PISTACHIOS_VALUE = 51;
    /**
     * <code>ALLERGEN_TYPE_CODE_POD_FRUITS = 52;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_POD_FRUITS_VALUE = 52;
    /**
     * <code>ALLERGEN_TYPE_CODE_QUEENSLAND_NUTS = 53;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_QUEENSLAND_NUTS_VALUE = 53;
    /**
     * <code>ALLERGEN_TYPE_CODE_RYE = 54;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_RYE_VALUE = 54;
    /**
     * <code>ALLERGEN_TYPE_CODE_SESAME_SEEDS = 55;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_SESAME_SEEDS_VALUE = 55;
    /**
     * <code>ALLERGEN_TYPE_CODE_SOYBEANS = 56;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_SOYBEANS_VALUE = 56;
    /**
     * <code>ALLERGEN_TYPE_CODE_SPELT = 57;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_SPELT_VALUE = 57;
    /**
     * <code>ALLERGEN_TYPE_CODE_SULPHUR_DIOXIDE = 58;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_SULPHUR_DIOXIDE_VALUE = 58;
    /**
     * <code>ALLERGEN_TYPE_CODE_TREE_NUTS = 59;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_TREE_NUTS_VALUE = 59;
    /**
     * <code>ALLERGEN_TYPE_CODE_TREE_NUT_TRACES = 60;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_TREE_NUT_TRACES_VALUE = 60;
    /**
     * <code>ALLERGEN_TYPE_CODE_WALNUTS = 61;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_WALNUTS_VALUE = 61;
    /**
     * <code>ALLERGEN_TYPE_CODE_WHEAT = 62;</code>
     */
    public static final int ALLERGEN_TYPE_CODE_WHEAT_VALUE = 62;


    public final int getNumber() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalArgumentException(
            "Can't get the number of an unknown enum value.");
      }
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static AllergenTypeCode valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static AllergenTypeCode forNumber(int value) {
      switch (value) {
        case 0: return ALLERGEN_TYPE_CODE_UNSPECIFIED;
        case 1: return ALLERGEN_TYPE_CODE_ALMONDS;
        case 2: return ALLERGEN_TYPE_CODE_ALPHA_ISOMETHYL_IONONE;
        case 3: return ALLERGEN_TYPE_CODE_ALCOHOL;
        case 4: return ALLERGEN_TYPE_CODE_AMYL_CINNAMAL;
        case 5: return ALLERGEN_TYPE_CODE_ANISE_ALCOHOL;
        case 6: return ALLERGEN_TYPE_CODE_BARLEY;
        case 7: return ALLERGEN_TYPE_CODE_BENZYL_ALCOHOL;
        case 8: return ALLERGEN_TYPE_CODE_BENZYL_BENZOATE;
        case 9: return ALLERGEN_TYPE_CODE_BENZYL_CINNAMATE;
        case 10: return ALLERGEN_TYPE_CODE_BENZYL_SALICYLATE;
        case 11: return ALLERGEN_TYPE_CODE_BRAZIL_NUTS;
        case 12: return ALLERGEN_TYPE_CODE_BUTYLPHENYL_METHYLPROPIONATE;
        case 13: return ALLERGEN_TYPE_CODE_CARROTS;
        case 14: return ALLERGEN_TYPE_CODE_CASHEW_NUTS;
        case 15: return ALLERGEN_TYPE_CODE_CELERY;
        case 16: return ALLERGEN_TYPE_CODE_CEREALS_CONTAINING_GLUTEN;
        case 17: return ALLERGEN_TYPE_CODE_CINNAMAL;
        case 18: return ALLERGEN_TYPE_CODE_CINNAMYL_ALCOHOL;
        case 19: return ALLERGEN_TYPE_CODE_CITRAL;
        case 20: return ALLERGEN_TYPE_CODE_CITRONELLOL;
        case 21: return ALLERGEN_TYPE_CODE_COCOA;
        case 22: return ALLERGEN_TYPE_CODE_CORIANDER;
        case 23: return ALLERGEN_TYPE_CODE_CORN;
        case 24: return ALLERGEN_TYPE_CODE_COUMARIN;
        case 25: return ALLERGEN_TYPE_CODE_CRUSTACEANS;
        case 26: return ALLERGEN_TYPE_CODE_EGGS;
        case 27: return ALLERGEN_TYPE_CODE_EUGENOL;
        case 28: return ALLERGEN_TYPE_CODE_EVERNIA_FURFURACEA;
        case 29: return ALLERGEN_TYPE_CODE_EVERNIA_PRUNASTRI;
        case 30: return ALLERGEN_TYPE_CODE_FARNESOL;
        case 31: return ALLERGEN_TYPE_CODE_FISH;
        case 32: return ALLERGEN_TYPE_CODE_GERANIOL;
        case 33: return ALLERGEN_TYPE_CODE_GLUTEN;
        case 34: return ALLERGEN_TYPE_CODE_HAZELNUTS;
        case 35: return ALLERGEN_TYPE_CODE_HEXYL_CINNAMAL;
        case 36: return ALLERGEN_TYPE_CODE_HYDROXYCITRONELLAL;
        case 37: return ALLERGEN_TYPE_CODE_HYDROXYISOHEXYL_3_CYCLOHEXENE_CARBOXALDEHYDE_ISOEUGENOL_LIMONENE_LINAL;
        case 38: return ALLERGEN_TYPE_CODE_KAMUT;
        case 39: return ALLERGEN_TYPE_CODE_LACTOSE;
        case 40: return ALLERGEN_TYPE_CODE_LUPINE;
        case 41: return ALLERGEN_TYPE_CODE_MACADAMIA_NUTS;
        case 42: return ALLERGEN_TYPE_CODE_METHYL_2_OCTYNOATE;
        case 43: return ALLERGEN_TYPE_CODE_MILK;
        case 44: return ALLERGEN_TYPE_CODE_MOLLUSCS;
        case 45: return ALLERGEN_TYPE_CODE_MUSTARD;
        case 46: return ALLERGEN_TYPE_CODE_NO_DECLARED_ALLERGENS;
        case 47: return ALLERGEN_TYPE_CODE_OAT;
        case 48: return ALLERGEN_TYPE_CODE_PEANUTS;
        case 49: return ALLERGEN_TYPE_CODE_PEAS;
        case 50: return ALLERGEN_TYPE_CODE_PECAN_NUTS;
        case 51: return ALLERGEN_TYPE_CODE_PISTACHIOS;
        case 52: return ALLERGEN_TYPE_CODE_POD_FRUITS;
        case 53: return ALLERGEN_TYPE_CODE_QUEENSLAND_NUTS;
        case 54: return ALLERGEN_TYPE_CODE_RYE;
        case 55: return ALLERGEN_TYPE_CODE_SESAME_SEEDS;
        case 56: return ALLERGEN_TYPE_CODE_SOYBEANS;
        case 57: return ALLERGEN_TYPE_CODE_SPELT;
        case 58: return ALLERGEN_TYPE_CODE_SULPHUR_DIOXIDE;
        case 59: return ALLERGEN_TYPE_CODE_TREE_NUTS;
        case 60: return ALLERGEN_TYPE_CODE_TREE_NUT_TRACES;
        case 61: return ALLERGEN_TYPE_CODE_WALNUTS;
        case 62: return ALLERGEN_TYPE_CODE_WHEAT;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<AllergenTypeCode>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        AllergenTypeCode> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<AllergenTypeCode>() {
            public AllergenTypeCode findValueByNumber(int number) {
              return AllergenTypeCode.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalStateException(
            "Can't get the descriptor of an unrecognized enum value.");
      }
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.getDescriptor().getEnumTypes().get(1);
    }

    private static final AllergenTypeCode[] VALUES = values();

    public static AllergenTypeCode valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      if (desc.getIndex() == -1) {
        return UNRECOGNIZED;
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private AllergenTypeCode(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:food.menu.v1.AllergenTypeCode)
  }

  /**
   * Protobuf enum {@code food.menu.v1.NutritionValueUnit}
   */
  public enum NutritionValueUnit
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Do not use. The nutrition value unit is not explicitly set.
     * </pre>
     *
     * <code>NUTRITION_VALUE_UNIT_UNSPECIFIED = 0;</code>
     */
    NUTRITION_VALUE_UNIT_UNSPECIFIED(0),
    /**
     * <pre>
     * Units used to express the amount of energy in a menu item.
     * </pre>
     *
     * <code>ENERGY_CALORIES = 1;</code>
     */
    ENERGY_CALORIES(1),
    /**
     * <code>ENERGY_KILOJOULES = 2;</code>
     */
    ENERGY_KILOJOULES(2),
    /**
     * <pre>
     * Units used to express the amount in weight a substance is present in the
     * menu item.
     * </pre>
     *
     * <code>WEIGHT_MILLIGRAMS = 3;</code>
     */
    WEIGHT_MILLIGRAMS(3),
    /**
     * <code>WEIGHT_GRAMS = 4;</code>
     */
    WEIGHT_GRAMS(4),
    UNRECOGNIZED(-1),
    ;

    /**
     * <pre>
     * Do not use. The nutrition value unit is not explicitly set.
     * </pre>
     *
     * <code>NUTRITION_VALUE_UNIT_UNSPECIFIED = 0;</code>
     */
    public static final int NUTRITION_VALUE_UNIT_UNSPECIFIED_VALUE = 0;
    /**
     * <pre>
     * Units used to express the amount of energy in a menu item.
     * </pre>
     *
     * <code>ENERGY_CALORIES = 1;</code>
     */
    public static final int ENERGY_CALORIES_VALUE = 1;
    /**
     * <code>ENERGY_KILOJOULES = 2;</code>
     */
    public static final int ENERGY_KILOJOULES_VALUE = 2;
    /**
     * <pre>
     * Units used to express the amount in weight a substance is present in the
     * menu item.
     * </pre>
     *
     * <code>WEIGHT_MILLIGRAMS = 3;</code>
     */
    public static final int WEIGHT_MILLIGRAMS_VALUE = 3;
    /**
     * <code>WEIGHT_GRAMS = 4;</code>
     */
    public static final int WEIGHT_GRAMS_VALUE = 4;


    public final int getNumber() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalArgumentException(
            "Can't get the number of an unknown enum value.");
      }
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static NutritionValueUnit valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static NutritionValueUnit forNumber(int value) {
      switch (value) {
        case 0: return NUTRITION_VALUE_UNIT_UNSPECIFIED;
        case 1: return ENERGY_CALORIES;
        case 2: return ENERGY_KILOJOULES;
        case 3: return WEIGHT_MILLIGRAMS;
        case 4: return WEIGHT_GRAMS;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<NutritionValueUnit>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        NutritionValueUnit> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<NutritionValueUnit>() {
            public NutritionValueUnit findValueByNumber(int number) {
              return NutritionValueUnit.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalStateException(
            "Can't get the descriptor of an unrecognized enum value.");
      }
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.getDescriptor().getEnumTypes().get(2);
    }

    private static final NutritionValueUnit[] VALUES = values();

    public static NutritionValueUnit valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      if (desc.getIndex() == -1) {
        return UNRECOGNIZED;
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private NutritionValueUnit(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:food.menu.v1.NutritionValueUnit)
  }

  /**
   * <pre>
   * Indicates the level of containment a food item has of a certain attribute,
   * such as allergens or additives.
   * </pre>
   *
   * Protobuf enum {@code food.menu.v1.ContainmentLevelCode}
   */
  public enum ContainmentLevelCode
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Do not use. The containment level code is not explicitly specified.
     * </pre>
     *
     * <code>CONTAINMENT_LEVEL_CODE_UNSPECIFIED = 0;</code>
     */
    CONTAINMENT_LEVEL_CODE_UNSPECIFIED(0),
    /**
     * <code>CONTAINMENT_LEVEL_CODE_CONTAINS = 1;</code>
     */
    CONTAINMENT_LEVEL_CODE_CONTAINS(1),
    /**
     * <code>CONTAINMENT_LEVEL_CODE_DOES_NOT_CONTAIN = 2;</code>
     */
    CONTAINMENT_LEVEL_CODE_DOES_NOT_CONTAIN(2),
    /**
     * <code>CONTAINMENT_LEVEL_CODE_MAY_CONTAIN = 3;</code>
     */
    CONTAINMENT_LEVEL_CODE_MAY_CONTAIN(3),
    UNRECOGNIZED(-1),
    ;

    /**
     * <pre>
     * Do not use. The containment level code is not explicitly specified.
     * </pre>
     *
     * <code>CONTAINMENT_LEVEL_CODE_UNSPECIFIED = 0;</code>
     */
    public static final int CONTAINMENT_LEVEL_CODE_UNSPECIFIED_VALUE = 0;
    /**
     * <code>CONTAINMENT_LEVEL_CODE_CONTAINS = 1;</code>
     */
    public static final int CONTAINMENT_LEVEL_CODE_CONTAINS_VALUE = 1;
    /**
     * <code>CONTAINMENT_LEVEL_CODE_DOES_NOT_CONTAIN = 2;</code>
     */
    public static final int CONTAINMENT_LEVEL_CODE_DOES_NOT_CONTAIN_VALUE = 2;
    /**
     * <code>CONTAINMENT_LEVEL_CODE_MAY_CONTAIN = 3;</code>
     */
    public static final int CONTAINMENT_LEVEL_CODE_MAY_CONTAIN_VALUE = 3;


    public final int getNumber() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalArgumentException(
            "Can't get the number of an unknown enum value.");
      }
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static ContainmentLevelCode valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static ContainmentLevelCode forNumber(int value) {
      switch (value) {
        case 0: return CONTAINMENT_LEVEL_CODE_UNSPECIFIED;
        case 1: return CONTAINMENT_LEVEL_CODE_CONTAINS;
        case 2: return CONTAINMENT_LEVEL_CODE_DOES_NOT_CONTAIN;
        case 3: return CONTAINMENT_LEVEL_CODE_MAY_CONTAIN;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<ContainmentLevelCode>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        ContainmentLevelCode> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<ContainmentLevelCode>() {
            public ContainmentLevelCode findValueByNumber(int number) {
              return ContainmentLevelCode.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalStateException(
            "Can't get the descriptor of an unrecognized enum value.");
      }
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.getDescriptor().getEnumTypes().get(3);
    }

    private static final ContainmentLevelCode[] VALUES = values();

    public static ContainmentLevelCode valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      if (desc.getIndex() == -1) {
        return UNRECOGNIZED;
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private ContainmentLevelCode(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:food.menu.v1.ContainmentLevelCode)
  }

  /**
   * <pre>
   * Indicates how to properly deposit a food item or bottle.
   * </pre>
   *
   * Protobuf enum {@code food.menu.v1.DepositCode}
   */
  public enum DepositCode
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Do not use. The deposite code is not explicitly specified.
     * </pre>
     *
     * <code>DEPOSIT_CODE_UNSPECIFIED = 0;</code>
     */
    DEPOSIT_CODE_UNSPECIFIED(0),
    /**
     * <code>DEPOSIT_CODE_REUSABLE = 1;</code>
     */
    DEPOSIT_CODE_REUSABLE(1),
    /**
     * <code>DEPOSIT_CODE_RECYCLABLE = 2;</code>
     */
    DEPOSIT_CODE_RECYCLABLE(2),
    UNRECOGNIZED(-1),
    ;

    /**
     * <pre>
     * Do not use. The deposite code is not explicitly specified.
     * </pre>
     *
     * <code>DEPOSIT_CODE_UNSPECIFIED = 0;</code>
     */
    public static final int DEPOSIT_CODE_UNSPECIFIED_VALUE = 0;
    /**
     * <code>DEPOSIT_CODE_REUSABLE = 1;</code>
     */
    public static final int DEPOSIT_CODE_REUSABLE_VALUE = 1;
    /**
     * <code>DEPOSIT_CODE_RECYCLABLE = 2;</code>
     */
    public static final int DEPOSIT_CODE_RECYCLABLE_VALUE = 2;


    public final int getNumber() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalArgumentException(
            "Can't get the number of an unknown enum value.");
      }
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static DepositCode valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static DepositCode forNumber(int value) {
      switch (value) {
        case 0: return DEPOSIT_CODE_UNSPECIFIED;
        case 1: return DEPOSIT_CODE_REUSABLE;
        case 2: return DEPOSIT_CODE_RECYCLABLE;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<DepositCode>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        DepositCode> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<DepositCode>() {
            public DepositCode findValueByNumber(int number) {
              return DepositCode.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalStateException(
            "Can't get the descriptor of an unrecognized enum value.");
      }
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.getDescriptor().getEnumTypes().get(4);
    }

    private static final DepositCode[] VALUES = values();

    public static DepositCode valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      if (desc.getIndex() == -1) {
        return UNRECOGNIZED;
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private DepositCode(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:food.menu.v1.DepositCode)
  }

  public interface FoodMenuFeedOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.FoodMenuFeed)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
     */
    java.util.List<food.menu.v1.FoodMenu.MenuComponent> 
        getDataList();
    /**
     * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
     */
    food.menu.v1.FoodMenu.MenuComponent getData(int index);
    /**
     * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
     */
    int getDataCount();
    /**
     * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
     */
    java.util.List<? extends food.menu.v1.FoodMenu.MenuComponentOrBuilder> 
        getDataOrBuilderList();
    /**
     * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
     */
    food.menu.v1.FoodMenu.MenuComponentOrBuilder getDataOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code food.menu.v1.FoodMenuFeed}
   */
  public static final class FoodMenuFeed extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.FoodMenuFeed)
      FoodMenuFeedOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use FoodMenuFeed.newBuilder() to construct.
    private FoodMenuFeed(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private FoodMenuFeed() {
      data_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new FoodMenuFeed();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_FoodMenuFeed_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_FoodMenuFeed_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.FoodMenuFeed.class, food.menu.v1.FoodMenu.FoodMenuFeed.Builder.class);
    }

    public static final int DATA_FIELD_NUMBER = 1;
    @SuppressWarnings("serial")
    private java.util.List<food.menu.v1.FoodMenu.MenuComponent> data_;
    /**
     * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
     */
    @java.lang.Override
    public java.util.List<food.menu.v1.FoodMenu.MenuComponent> getDataList() {
      return data_;
    }
    /**
     * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
     */
    @java.lang.Override
    public java.util.List<? extends food.menu.v1.FoodMenu.MenuComponentOrBuilder> 
        getDataOrBuilderList() {
      return data_;
    }
    /**
     * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
     */
    @java.lang.Override
    public int getDataCount() {
      return data_.size();
    }
    /**
     * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuComponent getData(int index) {
      return data_.get(index);
    }
    /**
     * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuComponentOrBuilder getDataOrBuilder(
        int index) {
      return data_.get(index);
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      for (int i = 0; i < data_.size(); i++) {
        output.writeMessage(1, data_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < data_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, data_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.FoodMenuFeed)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.FoodMenuFeed other = (food.menu.v1.FoodMenu.FoodMenuFeed) obj;

      if (!getDataList()
          .equals(other.getDataList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (getDataCount() > 0) {
        hash = (37 * hash) + DATA_FIELD_NUMBER;
        hash = (53 * hash) + getDataList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.FoodMenuFeed parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.FoodMenuFeed parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.FoodMenuFeed parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.FoodMenuFeed parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.FoodMenuFeed parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.FoodMenuFeed parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.FoodMenuFeed parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.FoodMenuFeed parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.FoodMenuFeed parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.FoodMenuFeed parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.FoodMenuFeed parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.FoodMenuFeed parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.FoodMenuFeed prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code food.menu.v1.FoodMenuFeed}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.FoodMenuFeed)
        food.menu.v1.FoodMenu.FoodMenuFeedOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_FoodMenuFeed_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_FoodMenuFeed_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.FoodMenuFeed.class, food.menu.v1.FoodMenu.FoodMenuFeed.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.FoodMenuFeed.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        if (dataBuilder_ == null) {
          data_ = java.util.Collections.emptyList();
        } else {
          data_ = null;
          dataBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_FoodMenuFeed_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.FoodMenuFeed getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.FoodMenuFeed.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.FoodMenuFeed build() {
        food.menu.v1.FoodMenu.FoodMenuFeed result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.FoodMenuFeed buildPartial() {
        food.menu.v1.FoodMenu.FoodMenuFeed result = new food.menu.v1.FoodMenu.FoodMenuFeed(this);
        buildPartialRepeatedFields(result);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartialRepeatedFields(food.menu.v1.FoodMenu.FoodMenuFeed result) {
        if (dataBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0)) {
            data_ = java.util.Collections.unmodifiableList(data_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.data_ = data_;
        } else {
          result.data_ = dataBuilder_.build();
        }
      }

      private void buildPartial0(food.menu.v1.FoodMenu.FoodMenuFeed result) {
        int from_bitField0_ = bitField0_;
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.FoodMenuFeed) {
          return mergeFrom((food.menu.v1.FoodMenu.FoodMenuFeed)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.FoodMenuFeed other) {
        if (other == food.menu.v1.FoodMenu.FoodMenuFeed.getDefaultInstance()) return this;
        if (dataBuilder_ == null) {
          if (!other.data_.isEmpty()) {
            if (data_.isEmpty()) {
              data_ = other.data_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureDataIsMutable();
              data_.addAll(other.data_);
            }
            onChanged();
          }
        } else {
          if (!other.data_.isEmpty()) {
            if (dataBuilder_.isEmpty()) {
              dataBuilder_.dispose();
              dataBuilder_ = null;
              data_ = other.data_;
              bitField0_ = (bitField0_ & ~0x00000001);
              dataBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getDataFieldBuilder() : null;
            } else {
              dataBuilder_.addAllMessages(other.data_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                food.menu.v1.FoodMenu.MenuComponent m =
                    input.readMessage(
                        food.menu.v1.FoodMenu.MenuComponent.parser(),
                        extensionRegistry);
                if (dataBuilder_ == null) {
                  ensureDataIsMutable();
                  data_.add(m);
                } else {
                  dataBuilder_.addMessage(m);
                }
                break;
              } // case 10
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.util.List<food.menu.v1.FoodMenu.MenuComponent> data_ =
        java.util.Collections.emptyList();
      private void ensureDataIsMutable() {
        if (!((bitField0_ & 0x00000001) != 0)) {
          data_ = new java.util.ArrayList<food.menu.v1.FoodMenu.MenuComponent>(data_);
          bitField0_ |= 0x00000001;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuComponent, food.menu.v1.FoodMenu.MenuComponent.Builder, food.menu.v1.FoodMenu.MenuComponentOrBuilder> dataBuilder_;

      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public java.util.List<food.menu.v1.FoodMenu.MenuComponent> getDataList() {
        if (dataBuilder_ == null) {
          return java.util.Collections.unmodifiableList(data_);
        } else {
          return dataBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public int getDataCount() {
        if (dataBuilder_ == null) {
          return data_.size();
        } else {
          return dataBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public food.menu.v1.FoodMenu.MenuComponent getData(int index) {
        if (dataBuilder_ == null) {
          return data_.get(index);
        } else {
          return dataBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public Builder setData(
          int index, food.menu.v1.FoodMenu.MenuComponent value) {
        if (dataBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureDataIsMutable();
          data_.set(index, value);
          onChanged();
        } else {
          dataBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public Builder setData(
          int index, food.menu.v1.FoodMenu.MenuComponent.Builder builderForValue) {
        if (dataBuilder_ == null) {
          ensureDataIsMutable();
          data_.set(index, builderForValue.build());
          onChanged();
        } else {
          dataBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public Builder addData(food.menu.v1.FoodMenu.MenuComponent value) {
        if (dataBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureDataIsMutable();
          data_.add(value);
          onChanged();
        } else {
          dataBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public Builder addData(
          int index, food.menu.v1.FoodMenu.MenuComponent value) {
        if (dataBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureDataIsMutable();
          data_.add(index, value);
          onChanged();
        } else {
          dataBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public Builder addData(
          food.menu.v1.FoodMenu.MenuComponent.Builder builderForValue) {
        if (dataBuilder_ == null) {
          ensureDataIsMutable();
          data_.add(builderForValue.build());
          onChanged();
        } else {
          dataBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public Builder addData(
          int index, food.menu.v1.FoodMenu.MenuComponent.Builder builderForValue) {
        if (dataBuilder_ == null) {
          ensureDataIsMutable();
          data_.add(index, builderForValue.build());
          onChanged();
        } else {
          dataBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public Builder addAllData(
          java.lang.Iterable<? extends food.menu.v1.FoodMenu.MenuComponent> values) {
        if (dataBuilder_ == null) {
          ensureDataIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, data_);
          onChanged();
        } else {
          dataBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public Builder clearData() {
        if (dataBuilder_ == null) {
          data_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          dataBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public Builder removeData(int index) {
        if (dataBuilder_ == null) {
          ensureDataIsMutable();
          data_.remove(index);
          onChanged();
        } else {
          dataBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public food.menu.v1.FoodMenu.MenuComponent.Builder getDataBuilder(
          int index) {
        return getDataFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public food.menu.v1.FoodMenu.MenuComponentOrBuilder getDataOrBuilder(
          int index) {
        if (dataBuilder_ == null) {
          return data_.get(index);  } else {
          return dataBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public java.util.List<? extends food.menu.v1.FoodMenu.MenuComponentOrBuilder> 
           getDataOrBuilderList() {
        if (dataBuilder_ != null) {
          return dataBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(data_);
        }
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public food.menu.v1.FoodMenu.MenuComponent.Builder addDataBuilder() {
        return getDataFieldBuilder().addBuilder(
            food.menu.v1.FoodMenu.MenuComponent.getDefaultInstance());
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public food.menu.v1.FoodMenu.MenuComponent.Builder addDataBuilder(
          int index) {
        return getDataFieldBuilder().addBuilder(
            index, food.menu.v1.FoodMenu.MenuComponent.getDefaultInstance());
      }
      /**
       * <code>repeated .food.menu.v1.MenuComponent data = 1;</code>
       */
      public java.util.List<food.menu.v1.FoodMenu.MenuComponent.Builder> 
           getDataBuilderList() {
        return getDataFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuComponent, food.menu.v1.FoodMenu.MenuComponent.Builder, food.menu.v1.FoodMenu.MenuComponentOrBuilder> 
          getDataFieldBuilder() {
        if (dataBuilder_ == null) {
          dataBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              food.menu.v1.FoodMenu.MenuComponent, food.menu.v1.FoodMenu.MenuComponent.Builder, food.menu.v1.FoodMenu.MenuComponentOrBuilder>(
                  data_,
                  ((bitField0_ & 0x00000001) != 0),
                  getParentForChildren(),
                  isClean());
          data_ = null;
        }
        return dataBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.FoodMenuFeed)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.FoodMenuFeed)
    private static final food.menu.v1.FoodMenu.FoodMenuFeed DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.FoodMenuFeed();
    }

    public static food.menu.v1.FoodMenu.FoodMenuFeed getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<FoodMenuFeed>
        PARSER = new com.google.protobuf.AbstractParser<FoodMenuFeed>() {
      @java.lang.Override
      public FoodMenuFeed parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<FoodMenuFeed> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<FoodMenuFeed> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.FoodMenuFeed getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface MenuComponentOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.MenuComponent)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>.food.menu.v1.Menu menu = 1;</code>
     * @return Whether the menu field is set.
     */
    boolean hasMenu();
    /**
     * <code>.food.menu.v1.Menu menu = 1;</code>
     * @return The menu.
     */
    food.menu.v1.FoodMenu.Menu getMenu();
    /**
     * <code>.food.menu.v1.Menu menu = 1;</code>
     */
    food.menu.v1.FoodMenu.MenuOrBuilder getMenuOrBuilder();

    /**
     * <code>.food.menu.v1.MenuSection section = 2;</code>
     * @return Whether the section field is set.
     */
    boolean hasSection();
    /**
     * <code>.food.menu.v1.MenuSection section = 2;</code>
     * @return The section.
     */
    food.menu.v1.FoodMenu.MenuSection getSection();
    /**
     * <code>.food.menu.v1.MenuSection section = 2;</code>
     */
    food.menu.v1.FoodMenu.MenuSectionOrBuilder getSectionOrBuilder();

    /**
     * <code>.food.menu.v1.MenuItem item = 3;</code>
     * @return Whether the item field is set.
     */
    boolean hasItem();
    /**
     * <code>.food.menu.v1.MenuItem item = 3;</code>
     * @return The item.
     */
    food.menu.v1.FoodMenu.MenuItem getItem();
    /**
     * <code>.food.menu.v1.MenuItem item = 3;</code>
     */
    food.menu.v1.FoodMenu.MenuItemOrBuilder getItemOrBuilder();

    /**
     * <code>.food.menu.v1.MenuItemOption option = 4;</code>
     * @return Whether the option field is set.
     */
    boolean hasOption();
    /**
     * <code>.food.menu.v1.MenuItemOption option = 4;</code>
     * @return The option.
     */
    food.menu.v1.FoodMenu.MenuItemOption getOption();
    /**
     * <code>.food.menu.v1.MenuItemOption option = 4;</code>
     */
    food.menu.v1.FoodMenu.MenuItemOptionOrBuilder getOptionOrBuilder();

    food.menu.v1.FoodMenu.MenuComponent.TypeCase getTypeCase();
  }
  /**
   * Protobuf type {@code food.menu.v1.MenuComponent}
   */
  public static final class MenuComponent extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.MenuComponent)
      MenuComponentOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use MenuComponent.newBuilder() to construct.
    private MenuComponent(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private MenuComponent() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new MenuComponent();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuComponent_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuComponent_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.MenuComponent.class, food.menu.v1.FoodMenu.MenuComponent.Builder.class);
    }

    private int typeCase_ = 0;
    @SuppressWarnings("serial")
    private java.lang.Object type_;
    public enum TypeCase
        implements com.google.protobuf.Internal.EnumLite,
            com.google.protobuf.AbstractMessage.InternalOneOfEnum {
      MENU(1),
      SECTION(2),
      ITEM(3),
      OPTION(4),
      TYPE_NOT_SET(0);
      private final int value;
      private TypeCase(int value) {
        this.value = value;
      }
      /**
       * @param value The number of the enum to look for.
       * @return The enum associated with the given number.
       * @deprecated Use {@link #forNumber(int)} instead.
       */
      @java.lang.Deprecated
      public static TypeCase valueOf(int value) {
        return forNumber(value);
      }

      public static TypeCase forNumber(int value) {
        switch (value) {
          case 1: return MENU;
          case 2: return SECTION;
          case 3: return ITEM;
          case 4: return OPTION;
          case 0: return TYPE_NOT_SET;
          default: return null;
        }
      }
      public int getNumber() {
        return this.value;
      }
    };

    public TypeCase
    getTypeCase() {
      return TypeCase.forNumber(
          typeCase_);
    }

    public static final int MENU_FIELD_NUMBER = 1;
    /**
     * <code>.food.menu.v1.Menu menu = 1;</code>
     * @return Whether the menu field is set.
     */
    @java.lang.Override
    public boolean hasMenu() {
      return typeCase_ == 1;
    }
    /**
     * <code>.food.menu.v1.Menu menu = 1;</code>
     * @return The menu.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.Menu getMenu() {
      if (typeCase_ == 1) {
         return (food.menu.v1.FoodMenu.Menu) type_;
      }
      return food.menu.v1.FoodMenu.Menu.getDefaultInstance();
    }
    /**
     * <code>.food.menu.v1.Menu menu = 1;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuOrBuilder getMenuOrBuilder() {
      if (typeCase_ == 1) {
         return (food.menu.v1.FoodMenu.Menu) type_;
      }
      return food.menu.v1.FoodMenu.Menu.getDefaultInstance();
    }

    public static final int SECTION_FIELD_NUMBER = 2;
    /**
     * <code>.food.menu.v1.MenuSection section = 2;</code>
     * @return Whether the section field is set.
     */
    @java.lang.Override
    public boolean hasSection() {
      return typeCase_ == 2;
    }
    /**
     * <code>.food.menu.v1.MenuSection section = 2;</code>
     * @return The section.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuSection getSection() {
      if (typeCase_ == 2) {
         return (food.menu.v1.FoodMenu.MenuSection) type_;
      }
      return food.menu.v1.FoodMenu.MenuSection.getDefaultInstance();
    }
    /**
     * <code>.food.menu.v1.MenuSection section = 2;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuSectionOrBuilder getSectionOrBuilder() {
      if (typeCase_ == 2) {
         return (food.menu.v1.FoodMenu.MenuSection) type_;
      }
      return food.menu.v1.FoodMenu.MenuSection.getDefaultInstance();
    }

    public static final int ITEM_FIELD_NUMBER = 3;
    /**
     * <code>.food.menu.v1.MenuItem item = 3;</code>
     * @return Whether the item field is set.
     */
    @java.lang.Override
    public boolean hasItem() {
      return typeCase_ == 3;
    }
    /**
     * <code>.food.menu.v1.MenuItem item = 3;</code>
     * @return The item.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItem getItem() {
      if (typeCase_ == 3) {
         return (food.menu.v1.FoodMenu.MenuItem) type_;
      }
      return food.menu.v1.FoodMenu.MenuItem.getDefaultInstance();
    }
    /**
     * <code>.food.menu.v1.MenuItem item = 3;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItemOrBuilder getItemOrBuilder() {
      if (typeCase_ == 3) {
         return (food.menu.v1.FoodMenu.MenuItem) type_;
      }
      return food.menu.v1.FoodMenu.MenuItem.getDefaultInstance();
    }

    public static final int OPTION_FIELD_NUMBER = 4;
    /**
     * <code>.food.menu.v1.MenuItemOption option = 4;</code>
     * @return Whether the option field is set.
     */
    @java.lang.Override
    public boolean hasOption() {
      return typeCase_ == 4;
    }
    /**
     * <code>.food.menu.v1.MenuItemOption option = 4;</code>
     * @return The option.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItemOption getOption() {
      if (typeCase_ == 4) {
         return (food.menu.v1.FoodMenu.MenuItemOption) type_;
      }
      return food.menu.v1.FoodMenu.MenuItemOption.getDefaultInstance();
    }
    /**
     * <code>.food.menu.v1.MenuItemOption option = 4;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItemOptionOrBuilder getOptionOrBuilder() {
      if (typeCase_ == 4) {
         return (food.menu.v1.FoodMenu.MenuItemOption) type_;
      }
      return food.menu.v1.FoodMenu.MenuItemOption.getDefaultInstance();
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (typeCase_ == 1) {
        output.writeMessage(1, (food.menu.v1.FoodMenu.Menu) type_);
      }
      if (typeCase_ == 2) {
        output.writeMessage(2, (food.menu.v1.FoodMenu.MenuSection) type_);
      }
      if (typeCase_ == 3) {
        output.writeMessage(3, (food.menu.v1.FoodMenu.MenuItem) type_);
      }
      if (typeCase_ == 4) {
        output.writeMessage(4, (food.menu.v1.FoodMenu.MenuItemOption) type_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (typeCase_ == 1) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, (food.menu.v1.FoodMenu.Menu) type_);
      }
      if (typeCase_ == 2) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, (food.menu.v1.FoodMenu.MenuSection) type_);
      }
      if (typeCase_ == 3) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, (food.menu.v1.FoodMenu.MenuItem) type_);
      }
      if (typeCase_ == 4) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, (food.menu.v1.FoodMenu.MenuItemOption) type_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.MenuComponent)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.MenuComponent other = (food.menu.v1.FoodMenu.MenuComponent) obj;

      if (!getTypeCase().equals(other.getTypeCase())) return false;
      switch (typeCase_) {
        case 1:
          if (!getMenu()
              .equals(other.getMenu())) return false;
          break;
        case 2:
          if (!getSection()
              .equals(other.getSection())) return false;
          break;
        case 3:
          if (!getItem()
              .equals(other.getItem())) return false;
          break;
        case 4:
          if (!getOption()
              .equals(other.getOption())) return false;
          break;
        case 0:
        default:
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      switch (typeCase_) {
        case 1:
          hash = (37 * hash) + MENU_FIELD_NUMBER;
          hash = (53 * hash) + getMenu().hashCode();
          break;
        case 2:
          hash = (37 * hash) + SECTION_FIELD_NUMBER;
          hash = (53 * hash) + getSection().hashCode();
          break;
        case 3:
          hash = (37 * hash) + ITEM_FIELD_NUMBER;
          hash = (53 * hash) + getItem().hashCode();
          break;
        case 4:
          hash = (37 * hash) + OPTION_FIELD_NUMBER;
          hash = (53 * hash) + getOption().hashCode();
          break;
        case 0:
        default:
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.MenuComponent parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuComponent parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuComponent parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuComponent parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuComponent parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuComponent parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuComponent parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuComponent parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuComponent parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuComponent parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuComponent parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuComponent parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.MenuComponent prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code food.menu.v1.MenuComponent}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.MenuComponent)
        food.menu.v1.FoodMenu.MenuComponentOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuComponent_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuComponent_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.MenuComponent.class, food.menu.v1.FoodMenu.MenuComponent.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.MenuComponent.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        if (menuBuilder_ != null) {
          menuBuilder_.clear();
        }
        if (sectionBuilder_ != null) {
          sectionBuilder_.clear();
        }
        if (itemBuilder_ != null) {
          itemBuilder_.clear();
        }
        if (optionBuilder_ != null) {
          optionBuilder_.clear();
        }
        typeCase_ = 0;
        type_ = null;
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuComponent_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuComponent getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.MenuComponent.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuComponent build() {
        food.menu.v1.FoodMenu.MenuComponent result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuComponent buildPartial() {
        food.menu.v1.FoodMenu.MenuComponent result = new food.menu.v1.FoodMenu.MenuComponent(this);
        if (bitField0_ != 0) { buildPartial0(result); }
        buildPartialOneofs(result);
        onBuilt();
        return result;
      }

      private void buildPartial0(food.menu.v1.FoodMenu.MenuComponent result) {
        int from_bitField0_ = bitField0_;
      }

      private void buildPartialOneofs(food.menu.v1.FoodMenu.MenuComponent result) {
        result.typeCase_ = typeCase_;
        result.type_ = this.type_;
        if (typeCase_ == 1 &&
            menuBuilder_ != null) {
          result.type_ = menuBuilder_.build();
        }
        if (typeCase_ == 2 &&
            sectionBuilder_ != null) {
          result.type_ = sectionBuilder_.build();
        }
        if (typeCase_ == 3 &&
            itemBuilder_ != null) {
          result.type_ = itemBuilder_.build();
        }
        if (typeCase_ == 4 &&
            optionBuilder_ != null) {
          result.type_ = optionBuilder_.build();
        }
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.MenuComponent) {
          return mergeFrom((food.menu.v1.FoodMenu.MenuComponent)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.MenuComponent other) {
        if (other == food.menu.v1.FoodMenu.MenuComponent.getDefaultInstance()) return this;
        switch (other.getTypeCase()) {
          case MENU: {
            mergeMenu(other.getMenu());
            break;
          }
          case SECTION: {
            mergeSection(other.getSection());
            break;
          }
          case ITEM: {
            mergeItem(other.getItem());
            break;
          }
          case OPTION: {
            mergeOption(other.getOption());
            break;
          }
          case TYPE_NOT_SET: {
            break;
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getMenuFieldBuilder().getBuilder(),
                    extensionRegistry);
                typeCase_ = 1;
                break;
              } // case 10
              case 18: {
                input.readMessage(
                    getSectionFieldBuilder().getBuilder(),
                    extensionRegistry);
                typeCase_ = 2;
                break;
              } // case 18
              case 26: {
                input.readMessage(
                    getItemFieldBuilder().getBuilder(),
                    extensionRegistry);
                typeCase_ = 3;
                break;
              } // case 26
              case 34: {
                input.readMessage(
                    getOptionFieldBuilder().getBuilder(),
                    extensionRegistry);
                typeCase_ = 4;
                break;
              } // case 34
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int typeCase_ = 0;
      private java.lang.Object type_;
      public TypeCase
          getTypeCase() {
        return TypeCase.forNumber(
            typeCase_);
      }

      public Builder clearType() {
        typeCase_ = 0;
        type_ = null;
        onChanged();
        return this;
      }

      private int bitField0_;

      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.Menu, food.menu.v1.FoodMenu.Menu.Builder, food.menu.v1.FoodMenu.MenuOrBuilder> menuBuilder_;
      /**
       * <code>.food.menu.v1.Menu menu = 1;</code>
       * @return Whether the menu field is set.
       */
      @java.lang.Override
      public boolean hasMenu() {
        return typeCase_ == 1;
      }
      /**
       * <code>.food.menu.v1.Menu menu = 1;</code>
       * @return The menu.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.Menu getMenu() {
        if (menuBuilder_ == null) {
          if (typeCase_ == 1) {
            return (food.menu.v1.FoodMenu.Menu) type_;
          }
          return food.menu.v1.FoodMenu.Menu.getDefaultInstance();
        } else {
          if (typeCase_ == 1) {
            return menuBuilder_.getMessage();
          }
          return food.menu.v1.FoodMenu.Menu.getDefaultInstance();
        }
      }
      /**
       * <code>.food.menu.v1.Menu menu = 1;</code>
       */
      public Builder setMenu(food.menu.v1.FoodMenu.Menu value) {
        if (menuBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          type_ = value;
          onChanged();
        } else {
          menuBuilder_.setMessage(value);
        }
        typeCase_ = 1;
        return this;
      }
      /**
       * <code>.food.menu.v1.Menu menu = 1;</code>
       */
      public Builder setMenu(
          food.menu.v1.FoodMenu.Menu.Builder builderForValue) {
        if (menuBuilder_ == null) {
          type_ = builderForValue.build();
          onChanged();
        } else {
          menuBuilder_.setMessage(builderForValue.build());
        }
        typeCase_ = 1;
        return this;
      }
      /**
       * <code>.food.menu.v1.Menu menu = 1;</code>
       */
      public Builder mergeMenu(food.menu.v1.FoodMenu.Menu value) {
        if (menuBuilder_ == null) {
          if (typeCase_ == 1 &&
              type_ != food.menu.v1.FoodMenu.Menu.getDefaultInstance()) {
            type_ = food.menu.v1.FoodMenu.Menu.newBuilder((food.menu.v1.FoodMenu.Menu) type_)
                .mergeFrom(value).buildPartial();
          } else {
            type_ = value;
          }
          onChanged();
        } else {
          if (typeCase_ == 1) {
            menuBuilder_.mergeFrom(value);
          } else {
            menuBuilder_.setMessage(value);
          }
        }
        typeCase_ = 1;
        return this;
      }
      /**
       * <code>.food.menu.v1.Menu menu = 1;</code>
       */
      public Builder clearMenu() {
        if (menuBuilder_ == null) {
          if (typeCase_ == 1) {
            typeCase_ = 0;
            type_ = null;
            onChanged();
          }
        } else {
          if (typeCase_ == 1) {
            typeCase_ = 0;
            type_ = null;
          }
          menuBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>.food.menu.v1.Menu menu = 1;</code>
       */
      public food.menu.v1.FoodMenu.Menu.Builder getMenuBuilder() {
        return getMenuFieldBuilder().getBuilder();
      }
      /**
       * <code>.food.menu.v1.Menu menu = 1;</code>
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuOrBuilder getMenuOrBuilder() {
        if ((typeCase_ == 1) && (menuBuilder_ != null)) {
          return menuBuilder_.getMessageOrBuilder();
        } else {
          if (typeCase_ == 1) {
            return (food.menu.v1.FoodMenu.Menu) type_;
          }
          return food.menu.v1.FoodMenu.Menu.getDefaultInstance();
        }
      }
      /**
       * <code>.food.menu.v1.Menu menu = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.Menu, food.menu.v1.FoodMenu.Menu.Builder, food.menu.v1.FoodMenu.MenuOrBuilder> 
          getMenuFieldBuilder() {
        if (menuBuilder_ == null) {
          if (!(typeCase_ == 1)) {
            type_ = food.menu.v1.FoodMenu.Menu.getDefaultInstance();
          }
          menuBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.Menu, food.menu.v1.FoodMenu.Menu.Builder, food.menu.v1.FoodMenu.MenuOrBuilder>(
                  (food.menu.v1.FoodMenu.Menu) type_,
                  getParentForChildren(),
                  isClean());
          type_ = null;
        }
        typeCase_ = 1;
        onChanged();
        return menuBuilder_;
      }

      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuSection, food.menu.v1.FoodMenu.MenuSection.Builder, food.menu.v1.FoodMenu.MenuSectionOrBuilder> sectionBuilder_;
      /**
       * <code>.food.menu.v1.MenuSection section = 2;</code>
       * @return Whether the section field is set.
       */
      @java.lang.Override
      public boolean hasSection() {
        return typeCase_ == 2;
      }
      /**
       * <code>.food.menu.v1.MenuSection section = 2;</code>
       * @return The section.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuSection getSection() {
        if (sectionBuilder_ == null) {
          if (typeCase_ == 2) {
            return (food.menu.v1.FoodMenu.MenuSection) type_;
          }
          return food.menu.v1.FoodMenu.MenuSection.getDefaultInstance();
        } else {
          if (typeCase_ == 2) {
            return sectionBuilder_.getMessage();
          }
          return food.menu.v1.FoodMenu.MenuSection.getDefaultInstance();
        }
      }
      /**
       * <code>.food.menu.v1.MenuSection section = 2;</code>
       */
      public Builder setSection(food.menu.v1.FoodMenu.MenuSection value) {
        if (sectionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          type_ = value;
          onChanged();
        } else {
          sectionBuilder_.setMessage(value);
        }
        typeCase_ = 2;
        return this;
      }
      /**
       * <code>.food.menu.v1.MenuSection section = 2;</code>
       */
      public Builder setSection(
          food.menu.v1.FoodMenu.MenuSection.Builder builderForValue) {
        if (sectionBuilder_ == null) {
          type_ = builderForValue.build();
          onChanged();
        } else {
          sectionBuilder_.setMessage(builderForValue.build());
        }
        typeCase_ = 2;
        return this;
      }
      /**
       * <code>.food.menu.v1.MenuSection section = 2;</code>
       */
      public Builder mergeSection(food.menu.v1.FoodMenu.MenuSection value) {
        if (sectionBuilder_ == null) {
          if (typeCase_ == 2 &&
              type_ != food.menu.v1.FoodMenu.MenuSection.getDefaultInstance()) {
            type_ = food.menu.v1.FoodMenu.MenuSection.newBuilder((food.menu.v1.FoodMenu.MenuSection) type_)
                .mergeFrom(value).buildPartial();
          } else {
            type_ = value;
          }
          onChanged();
        } else {
          if (typeCase_ == 2) {
            sectionBuilder_.mergeFrom(value);
          } else {
            sectionBuilder_.setMessage(value);
          }
        }
        typeCase_ = 2;
        return this;
      }
      /**
       * <code>.food.menu.v1.MenuSection section = 2;</code>
       */
      public Builder clearSection() {
        if (sectionBuilder_ == null) {
          if (typeCase_ == 2) {
            typeCase_ = 0;
            type_ = null;
            onChanged();
          }
        } else {
          if (typeCase_ == 2) {
            typeCase_ = 0;
            type_ = null;
          }
          sectionBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>.food.menu.v1.MenuSection section = 2;</code>
       */
      public food.menu.v1.FoodMenu.MenuSection.Builder getSectionBuilder() {
        return getSectionFieldBuilder().getBuilder();
      }
      /**
       * <code>.food.menu.v1.MenuSection section = 2;</code>
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuSectionOrBuilder getSectionOrBuilder() {
        if ((typeCase_ == 2) && (sectionBuilder_ != null)) {
          return sectionBuilder_.getMessageOrBuilder();
        } else {
          if (typeCase_ == 2) {
            return (food.menu.v1.FoodMenu.MenuSection) type_;
          }
          return food.menu.v1.FoodMenu.MenuSection.getDefaultInstance();
        }
      }
      /**
       * <code>.food.menu.v1.MenuSection section = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuSection, food.menu.v1.FoodMenu.MenuSection.Builder, food.menu.v1.FoodMenu.MenuSectionOrBuilder> 
          getSectionFieldBuilder() {
        if (sectionBuilder_ == null) {
          if (!(typeCase_ == 2)) {
            type_ = food.menu.v1.FoodMenu.MenuSection.getDefaultInstance();
          }
          sectionBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.MenuSection, food.menu.v1.FoodMenu.MenuSection.Builder, food.menu.v1.FoodMenu.MenuSectionOrBuilder>(
                  (food.menu.v1.FoodMenu.MenuSection) type_,
                  getParentForChildren(),
                  isClean());
          type_ = null;
        }
        typeCase_ = 2;
        onChanged();
        return sectionBuilder_;
      }

      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuItem, food.menu.v1.FoodMenu.MenuItem.Builder, food.menu.v1.FoodMenu.MenuItemOrBuilder> itemBuilder_;
      /**
       * <code>.food.menu.v1.MenuItem item = 3;</code>
       * @return Whether the item field is set.
       */
      @java.lang.Override
      public boolean hasItem() {
        return typeCase_ == 3;
      }
      /**
       * <code>.food.menu.v1.MenuItem item = 3;</code>
       * @return The item.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItem getItem() {
        if (itemBuilder_ == null) {
          if (typeCase_ == 3) {
            return (food.menu.v1.FoodMenu.MenuItem) type_;
          }
          return food.menu.v1.FoodMenu.MenuItem.getDefaultInstance();
        } else {
          if (typeCase_ == 3) {
            return itemBuilder_.getMessage();
          }
          return food.menu.v1.FoodMenu.MenuItem.getDefaultInstance();
        }
      }
      /**
       * <code>.food.menu.v1.MenuItem item = 3;</code>
       */
      public Builder setItem(food.menu.v1.FoodMenu.MenuItem value) {
        if (itemBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          type_ = value;
          onChanged();
        } else {
          itemBuilder_.setMessage(value);
        }
        typeCase_ = 3;
        return this;
      }
      /**
       * <code>.food.menu.v1.MenuItem item = 3;</code>
       */
      public Builder setItem(
          food.menu.v1.FoodMenu.MenuItem.Builder builderForValue) {
        if (itemBuilder_ == null) {
          type_ = builderForValue.build();
          onChanged();
        } else {
          itemBuilder_.setMessage(builderForValue.build());
        }
        typeCase_ = 3;
        return this;
      }
      /**
       * <code>.food.menu.v1.MenuItem item = 3;</code>
       */
      public Builder mergeItem(food.menu.v1.FoodMenu.MenuItem value) {
        if (itemBuilder_ == null) {
          if (typeCase_ == 3 &&
              type_ != food.menu.v1.FoodMenu.MenuItem.getDefaultInstance()) {
            type_ = food.menu.v1.FoodMenu.MenuItem.newBuilder((food.menu.v1.FoodMenu.MenuItem) type_)
                .mergeFrom(value).buildPartial();
          } else {
            type_ = value;
          }
          onChanged();
        } else {
          if (typeCase_ == 3) {
            itemBuilder_.mergeFrom(value);
          } else {
            itemBuilder_.setMessage(value);
          }
        }
        typeCase_ = 3;
        return this;
      }
      /**
       * <code>.food.menu.v1.MenuItem item = 3;</code>
       */
      public Builder clearItem() {
        if (itemBuilder_ == null) {
          if (typeCase_ == 3) {
            typeCase_ = 0;
            type_ = null;
            onChanged();
          }
        } else {
          if (typeCase_ == 3) {
            typeCase_ = 0;
            type_ = null;
          }
          itemBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>.food.menu.v1.MenuItem item = 3;</code>
       */
      public food.menu.v1.FoodMenu.MenuItem.Builder getItemBuilder() {
        return getItemFieldBuilder().getBuilder();
      }
      /**
       * <code>.food.menu.v1.MenuItem item = 3;</code>
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemOrBuilder getItemOrBuilder() {
        if ((typeCase_ == 3) && (itemBuilder_ != null)) {
          return itemBuilder_.getMessageOrBuilder();
        } else {
          if (typeCase_ == 3) {
            return (food.menu.v1.FoodMenu.MenuItem) type_;
          }
          return food.menu.v1.FoodMenu.MenuItem.getDefaultInstance();
        }
      }
      /**
       * <code>.food.menu.v1.MenuItem item = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuItem, food.menu.v1.FoodMenu.MenuItem.Builder, food.menu.v1.FoodMenu.MenuItemOrBuilder> 
          getItemFieldBuilder() {
        if (itemBuilder_ == null) {
          if (!(typeCase_ == 3)) {
            type_ = food.menu.v1.FoodMenu.MenuItem.getDefaultInstance();
          }
          itemBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.MenuItem, food.menu.v1.FoodMenu.MenuItem.Builder, food.menu.v1.FoodMenu.MenuItemOrBuilder>(
                  (food.menu.v1.FoodMenu.MenuItem) type_,
                  getParentForChildren(),
                  isClean());
          type_ = null;
        }
        typeCase_ = 3;
        onChanged();
        return itemBuilder_;
      }

      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuItemOption, food.menu.v1.FoodMenu.MenuItemOption.Builder, food.menu.v1.FoodMenu.MenuItemOptionOrBuilder> optionBuilder_;
      /**
       * <code>.food.menu.v1.MenuItemOption option = 4;</code>
       * @return Whether the option field is set.
       */
      @java.lang.Override
      public boolean hasOption() {
        return typeCase_ == 4;
      }
      /**
       * <code>.food.menu.v1.MenuItemOption option = 4;</code>
       * @return The option.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemOption getOption() {
        if (optionBuilder_ == null) {
          if (typeCase_ == 4) {
            return (food.menu.v1.FoodMenu.MenuItemOption) type_;
          }
          return food.menu.v1.FoodMenu.MenuItemOption.getDefaultInstance();
        } else {
          if (typeCase_ == 4) {
            return optionBuilder_.getMessage();
          }
          return food.menu.v1.FoodMenu.MenuItemOption.getDefaultInstance();
        }
      }
      /**
       * <code>.food.menu.v1.MenuItemOption option = 4;</code>
       */
      public Builder setOption(food.menu.v1.FoodMenu.MenuItemOption value) {
        if (optionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          type_ = value;
          onChanged();
        } else {
          optionBuilder_.setMessage(value);
        }
        typeCase_ = 4;
        return this;
      }
      /**
       * <code>.food.menu.v1.MenuItemOption option = 4;</code>
       */
      public Builder setOption(
          food.menu.v1.FoodMenu.MenuItemOption.Builder builderForValue) {
        if (optionBuilder_ == null) {
          type_ = builderForValue.build();
          onChanged();
        } else {
          optionBuilder_.setMessage(builderForValue.build());
        }
        typeCase_ = 4;
        return this;
      }
      /**
       * <code>.food.menu.v1.MenuItemOption option = 4;</code>
       */
      public Builder mergeOption(food.menu.v1.FoodMenu.MenuItemOption value) {
        if (optionBuilder_ == null) {
          if (typeCase_ == 4 &&
              type_ != food.menu.v1.FoodMenu.MenuItemOption.getDefaultInstance()) {
            type_ = food.menu.v1.FoodMenu.MenuItemOption.newBuilder((food.menu.v1.FoodMenu.MenuItemOption) type_)
                .mergeFrom(value).buildPartial();
          } else {
            type_ = value;
          }
          onChanged();
        } else {
          if (typeCase_ == 4) {
            optionBuilder_.mergeFrom(value);
          } else {
            optionBuilder_.setMessage(value);
          }
        }
        typeCase_ = 4;
        return this;
      }
      /**
       * <code>.food.menu.v1.MenuItemOption option = 4;</code>
       */
      public Builder clearOption() {
        if (optionBuilder_ == null) {
          if (typeCase_ == 4) {
            typeCase_ = 0;
            type_ = null;
            onChanged();
          }
        } else {
          if (typeCase_ == 4) {
            typeCase_ = 0;
            type_ = null;
          }
          optionBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>.food.menu.v1.MenuItemOption option = 4;</code>
       */
      public food.menu.v1.FoodMenu.MenuItemOption.Builder getOptionBuilder() {
        return getOptionFieldBuilder().getBuilder();
      }
      /**
       * <code>.food.menu.v1.MenuItemOption option = 4;</code>
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemOptionOrBuilder getOptionOrBuilder() {
        if ((typeCase_ == 4) && (optionBuilder_ != null)) {
          return optionBuilder_.getMessageOrBuilder();
        } else {
          if (typeCase_ == 4) {
            return (food.menu.v1.FoodMenu.MenuItemOption) type_;
          }
          return food.menu.v1.FoodMenu.MenuItemOption.getDefaultInstance();
        }
      }
      /**
       * <code>.food.menu.v1.MenuItemOption option = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuItemOption, food.menu.v1.FoodMenu.MenuItemOption.Builder, food.menu.v1.FoodMenu.MenuItemOptionOrBuilder> 
          getOptionFieldBuilder() {
        if (optionBuilder_ == null) {
          if (!(typeCase_ == 4)) {
            type_ = food.menu.v1.FoodMenu.MenuItemOption.getDefaultInstance();
          }
          optionBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.MenuItemOption, food.menu.v1.FoodMenu.MenuItemOption.Builder, food.menu.v1.FoodMenu.MenuItemOptionOrBuilder>(
                  (food.menu.v1.FoodMenu.MenuItemOption) type_,
                  getParentForChildren(),
                  isClean());
          type_ = null;
        }
        typeCase_ = 4;
        onChanged();
        return optionBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.MenuComponent)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.MenuComponent)
    private static final food.menu.v1.FoodMenu.MenuComponent DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.MenuComponent();
    }

    public static food.menu.v1.FoodMenu.MenuComponent getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<MenuComponent>
        PARSER = new com.google.protobuf.AbstractParser<MenuComponent>() {
      @java.lang.Override
      public MenuComponent parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<MenuComponent> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<MenuComponent> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuComponent getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface MenuOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.Menu)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * An opaque string from a partner which uniquely identifies the Menu within
     * the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_id = 1;</code>
     * @return The menuId.
     */
    java.lang.String getMenuId();
    /**
     * <pre>
     * An opaque string from a partner which uniquely identifies the Menu within
     * the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_id = 1;</code>
     * @return The bytes for menuId.
     */
    com.google.protobuf.ByteString
        getMenuIdBytes();

    /**
     * <pre>
     * The merchants to whom the menu apply.
     * Note: This field is repeated so chain restaurants can share the same menu
     * across multiple locations, each of which is a separate merchant.
     * Required.
     * </pre>
     *
     * <code>repeated string merchant_ids = 2;</code>
     * @return A list containing the merchantIds.
     */
    java.util.List<java.lang.String>
        getMerchantIdsList();
    /**
     * <pre>
     * The merchants to whom the menu apply.
     * Note: This field is repeated so chain restaurants can share the same menu
     * across multiple locations, each of which is a separate merchant.
     * Required.
     * </pre>
     *
     * <code>repeated string merchant_ids = 2;</code>
     * @return The count of merchantIds.
     */
    int getMerchantIdsCount();
    /**
     * <pre>
     * The merchants to whom the menu apply.
     * Note: This field is repeated so chain restaurants can share the same menu
     * across multiple locations, each of which is a separate merchant.
     * Required.
     * </pre>
     *
     * <code>repeated string merchant_ids = 2;</code>
     * @param index The index of the element to return.
     * @return The merchantIds at the given index.
     */
    java.lang.String getMerchantIds(int index);
    /**
     * <pre>
     * The merchants to whom the menu apply.
     * Note: This field is repeated so chain restaurants can share the same menu
     * across multiple locations, each of which is a separate merchant.
     * Required.
     * </pre>
     *
     * <code>repeated string merchant_ids = 2;</code>
     * @param index The index of the value to return.
     * @return The bytes of the merchantIds at the given index.
     */
    com.google.protobuf.ByteString
        getMerchantIdsBytes(int index);

    /**
     * <pre>
     * The name that can identify the Menu when a user is browsing the menu.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 3;</code>
     * @return Whether the displayName field is set.
     */
    boolean hasDisplayName();
    /**
     * <pre>
     * The name that can identify the Menu when a user is browsing the menu.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 3;</code>
     * @return The displayName.
     */
    food.menu.v1.FoodMenu.TextField getDisplayName();
    /**
     * <pre>
     * The name that can identify the Menu when a user is browsing the menu.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 3;</code>
     */
    food.menu.v1.FoodMenu.TextFieldOrBuilder getDisplayNameOrBuilder();

    /**
     * <pre>
     * The default language code associated with the text labels contained in the
     * menu. Expects BCP-47 language code, such as "en-US" or "sr-Latn".
     *
     * For more information, see
     * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
     * Optional.
     * </pre>
     *
     * <code>string language = 4;</code>
     * @return The language.
     */
    java.lang.String getLanguage();
    /**
     * <pre>
     * The default language code associated with the text labels contained in the
     * menu. Expects BCP-47 language code, such as "en-US" or "sr-Latn".
     *
     * For more information, see
     * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
     * Optional.
     * </pre>
     *
     * <code>string language = 4;</code>
     * @return The bytes for language.
     */
    com.google.protobuf.ByteString
        getLanguageBytes();

    /**
     * <pre>
     * Disclaimer to be shown to the user for the menu. For example, nutritional
     * information disclosure and allergen disclosure.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
     * @return Whether the disclaimer field is set.
     */
    boolean hasDisclaimer();
    /**
     * <pre>
     * Disclaimer to be shown to the user for the menu. For example, nutritional
     * information disclosure and allergen disclosure.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
     * @return The disclaimer.
     */
    food.menu.v1.FoodMenu.Disclaimer getDisclaimer();
    /**
     * <pre>
     * Disclaimer to be shown to the user for the menu. For example, nutritional
     * information disclosure and allergen disclosure.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
     */
    food.menu.v1.FoodMenu.DisclaimerOrBuilder getDisclaimerOrBuilder();

    /**
     * <pre>
     * IDs of items contained within this menu. Expects first-level menu items
     * only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @return A list containing the menuItemIds.
     */
    java.util.List<java.lang.String>
        getMenuItemIdsList();
    /**
     * <pre>
     * IDs of items contained within this menu. Expects first-level menu items
     * only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @return The count of menuItemIds.
     */
    int getMenuItemIdsCount();
    /**
     * <pre>
     * IDs of items contained within this menu. Expects first-level menu items
     * only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @param index The index of the element to return.
     * @return The menuItemIds at the given index.
     */
    java.lang.String getMenuItemIds(int index);
    /**
     * <pre>
     * IDs of items contained within this menu. Expects first-level menu items
     * only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @param index The index of the value to return.
     * @return The bytes of the menuItemIds at the given index.
     */
    com.google.protobuf.ByteString
        getMenuItemIdsBytes(int index);

    /**
     * <pre>
     * IDs of sections contained within this menu. Expects first-level menu
     * sections only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @return A list containing the menuSectionIds.
     */
    java.util.List<java.lang.String>
        getMenuSectionIdsList();
    /**
     * <pre>
     * IDs of sections contained within this menu. Expects first-level menu
     * sections only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @return The count of menuSectionIds.
     */
    int getMenuSectionIdsCount();
    /**
     * <pre>
     * IDs of sections contained within this menu. Expects first-level menu
     * sections only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @param index The index of the element to return.
     * @return The menuSectionIds at the given index.
     */
    java.lang.String getMenuSectionIds(int index);
    /**
     * <pre>
     * IDs of sections contained within this menu. Expects first-level menu
     * sections only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @param index The index of the value to return.
     * @return The bytes of the menuSectionIds at the given index.
     */
    com.google.protobuf.ByteString
        getMenuSectionIdsBytes(int index);

    /**
     * <pre>
     * Timestamp when this Menu or any of its contents was last updated by the
     * restaurant; i.e. a date to be associated with the phrase “accurate as of
     * date”.
     * Optional.
     * </pre>
     *
     * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
     * @return Whether the lastMerchantUpdateTime field is set.
     */
    boolean hasLastMerchantUpdateTime();
    /**
     * <pre>
     * Timestamp when this Menu or any of its contents was last updated by the
     * restaurant; i.e. a date to be associated with the phrase “accurate as of
     * date”.
     * Optional.
     * </pre>
     *
     * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
     * @return The lastMerchantUpdateTime.
     */
    com.google.protobuf.Timestamp getLastMerchantUpdateTime();
    /**
     * <pre>
     * Timestamp when this Menu or any of its contents was last updated by the
     * restaurant; i.e. a date to be associated with the phrase “accurate as of
     * date”.
     * Optional.
     * </pre>
     *
     * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
     */
    com.google.protobuf.TimestampOrBuilder getLastMerchantUpdateTimeOrBuilder();
  }
  /**
   * <pre>
   * Top-level catalog of food items offered by a Food establishment. Menu
   * contains a list of merchant ids and the menu that apply to those merchants.
   * A Menu can be used to represent single merchant with the menu, or multiple
   * merchants (typically chain restaurants) with the menus.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.Menu}
   */
  public static final class Menu extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.Menu)
      MenuOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Menu.newBuilder() to construct.
    private Menu(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Menu() {
      menuId_ = "";
      merchantIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
      language_ = "";
      menuItemIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
      menuSectionIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new Menu();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Menu_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Menu_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.Menu.class, food.menu.v1.FoodMenu.Menu.Builder.class);
    }

    public static final int MENU_ID_FIELD_NUMBER = 1;
    @SuppressWarnings("serial")
    private volatile java.lang.Object menuId_ = "";
    /**
     * <pre>
     * An opaque string from a partner which uniquely identifies the Menu within
     * the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_id = 1;</code>
     * @return The menuId.
     */
    @java.lang.Override
    public java.lang.String getMenuId() {
      java.lang.Object ref = menuId_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        menuId_ = s;
        return s;
      }
    }
    /**
     * <pre>
     * An opaque string from a partner which uniquely identifies the Menu within
     * the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_id = 1;</code>
     * @return The bytes for menuId.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getMenuIdBytes() {
      java.lang.Object ref = menuId_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        menuId_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int MERCHANT_IDS_FIELD_NUMBER = 2;
    @SuppressWarnings("serial")
    private com.google.protobuf.LazyStringArrayList merchantIds_ =
        com.google.protobuf.LazyStringArrayList.emptyList();
    /**
     * <pre>
     * The merchants to whom the menu apply.
     * Note: This field is repeated so chain restaurants can share the same menu
     * across multiple locations, each of which is a separate merchant.
     * Required.
     * </pre>
     *
     * <code>repeated string merchant_ids = 2;</code>
     * @return A list containing the merchantIds.
     */
    public com.google.protobuf.ProtocolStringList
        getMerchantIdsList() {
      return merchantIds_;
    }
    /**
     * <pre>
     * The merchants to whom the menu apply.
     * Note: This field is repeated so chain restaurants can share the same menu
     * across multiple locations, each of which is a separate merchant.
     * Required.
     * </pre>
     *
     * <code>repeated string merchant_ids = 2;</code>
     * @return The count of merchantIds.
     */
    public int getMerchantIdsCount() {
      return merchantIds_.size();
    }
    /**
     * <pre>
     * The merchants to whom the menu apply.
     * Note: This field is repeated so chain restaurants can share the same menu
     * across multiple locations, each of which is a separate merchant.
     * Required.
     * </pre>
     *
     * <code>repeated string merchant_ids = 2;</code>
     * @param index The index of the element to return.
     * @return The merchantIds at the given index.
     */
    public java.lang.String getMerchantIds(int index) {
      return merchantIds_.get(index);
    }
    /**
     * <pre>
     * The merchants to whom the menu apply.
     * Note: This field is repeated so chain restaurants can share the same menu
     * across multiple locations, each of which is a separate merchant.
     * Required.
     * </pre>
     *
     * <code>repeated string merchant_ids = 2;</code>
     * @param index The index of the value to return.
     * @return The bytes of the merchantIds at the given index.
     */
    public com.google.protobuf.ByteString
        getMerchantIdsBytes(int index) {
      return merchantIds_.getByteString(index);
    }

    public static final int DISPLAY_NAME_FIELD_NUMBER = 3;
    private food.menu.v1.FoodMenu.TextField displayName_;
    /**
     * <pre>
     * The name that can identify the Menu when a user is browsing the menu.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 3;</code>
     * @return Whether the displayName field is set.
     */
    @java.lang.Override
    public boolean hasDisplayName() {
      return displayName_ != null;
    }
    /**
     * <pre>
     * The name that can identify the Menu when a user is browsing the menu.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 3;</code>
     * @return The displayName.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextField getDisplayName() {
      return displayName_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : displayName_;
    }
    /**
     * <pre>
     * The name that can identify the Menu when a user is browsing the menu.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 3;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextFieldOrBuilder getDisplayNameOrBuilder() {
      return displayName_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : displayName_;
    }

    public static final int LANGUAGE_FIELD_NUMBER = 4;
    @SuppressWarnings("serial")
    private volatile java.lang.Object language_ = "";
    /**
     * <pre>
     * The default language code associated with the text labels contained in the
     * menu. Expects BCP-47 language code, such as "en-US" or "sr-Latn".
     *
     * For more information, see
     * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
     * Optional.
     * </pre>
     *
     * <code>string language = 4;</code>
     * @return The language.
     */
    @java.lang.Override
    public java.lang.String getLanguage() {
      java.lang.Object ref = language_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        language_ = s;
        return s;
      }
    }
    /**
     * <pre>
     * The default language code associated with the text labels contained in the
     * menu. Expects BCP-47 language code, such as "en-US" or "sr-Latn".
     *
     * For more information, see
     * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
     * Optional.
     * </pre>
     *
     * <code>string language = 4;</code>
     * @return The bytes for language.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getLanguageBytes() {
      java.lang.Object ref = language_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        language_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int DISCLAIMER_FIELD_NUMBER = 5;
    private food.menu.v1.FoodMenu.Disclaimer disclaimer_;
    /**
     * <pre>
     * Disclaimer to be shown to the user for the menu. For example, nutritional
     * information disclosure and allergen disclosure.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
     * @return Whether the disclaimer field is set.
     */
    @java.lang.Override
    public boolean hasDisclaimer() {
      return disclaimer_ != null;
    }
    /**
     * <pre>
     * Disclaimer to be shown to the user for the menu. For example, nutritional
     * information disclosure and allergen disclosure.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
     * @return The disclaimer.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.Disclaimer getDisclaimer() {
      return disclaimer_ == null ? food.menu.v1.FoodMenu.Disclaimer.getDefaultInstance() : disclaimer_;
    }
    /**
     * <pre>
     * Disclaimer to be shown to the user for the menu. For example, nutritional
     * information disclosure and allergen disclosure.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.DisclaimerOrBuilder getDisclaimerOrBuilder() {
      return disclaimer_ == null ? food.menu.v1.FoodMenu.Disclaimer.getDefaultInstance() : disclaimer_;
    }

    public static final int MENU_ITEM_IDS_FIELD_NUMBER = 6;
    @SuppressWarnings("serial")
    private com.google.protobuf.LazyStringArrayList menuItemIds_ =
        com.google.protobuf.LazyStringArrayList.emptyList();
    /**
     * <pre>
     * IDs of items contained within this menu. Expects first-level menu items
     * only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @return A list containing the menuItemIds.
     */
    public com.google.protobuf.ProtocolStringList
        getMenuItemIdsList() {
      return menuItemIds_;
    }
    /**
     * <pre>
     * IDs of items contained within this menu. Expects first-level menu items
     * only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @return The count of menuItemIds.
     */
    public int getMenuItemIdsCount() {
      return menuItemIds_.size();
    }
    /**
     * <pre>
     * IDs of items contained within this menu. Expects first-level menu items
     * only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @param index The index of the element to return.
     * @return The menuItemIds at the given index.
     */
    public java.lang.String getMenuItemIds(int index) {
      return menuItemIds_.get(index);
    }
    /**
     * <pre>
     * IDs of items contained within this menu. Expects first-level menu items
     * only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @param index The index of the value to return.
     * @return The bytes of the menuItemIds at the given index.
     */
    public com.google.protobuf.ByteString
        getMenuItemIdsBytes(int index) {
      return menuItemIds_.getByteString(index);
    }

    public static final int MENU_SECTION_IDS_FIELD_NUMBER = 7;
    @SuppressWarnings("serial")
    private com.google.protobuf.LazyStringArrayList menuSectionIds_ =
        com.google.protobuf.LazyStringArrayList.emptyList();
    /**
     * <pre>
     * IDs of sections contained within this menu. Expects first-level menu
     * sections only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @return A list containing the menuSectionIds.
     */
    public com.google.protobuf.ProtocolStringList
        getMenuSectionIdsList() {
      return menuSectionIds_;
    }
    /**
     * <pre>
     * IDs of sections contained within this menu. Expects first-level menu
     * sections only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @return The count of menuSectionIds.
     */
    public int getMenuSectionIdsCount() {
      return menuSectionIds_.size();
    }
    /**
     * <pre>
     * IDs of sections contained within this menu. Expects first-level menu
     * sections only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @param index The index of the element to return.
     * @return The menuSectionIds at the given index.
     */
    public java.lang.String getMenuSectionIds(int index) {
      return menuSectionIds_.get(index);
    }
    /**
     * <pre>
     * IDs of sections contained within this menu. Expects first-level menu
     * sections only.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @param index The index of the value to return.
     * @return The bytes of the menuSectionIds at the given index.
     */
    public com.google.protobuf.ByteString
        getMenuSectionIdsBytes(int index) {
      return menuSectionIds_.getByteString(index);
    }

    public static final int LAST_MERCHANT_UPDATE_TIME_FIELD_NUMBER = 8;
    private com.google.protobuf.Timestamp lastMerchantUpdateTime_;
    /**
     * <pre>
     * Timestamp when this Menu or any of its contents was last updated by the
     * restaurant; i.e. a date to be associated with the phrase “accurate as of
     * date”.
     * Optional.
     * </pre>
     *
     * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
     * @return Whether the lastMerchantUpdateTime field is set.
     */
    @java.lang.Override
    public boolean hasLastMerchantUpdateTime() {
      return lastMerchantUpdateTime_ != null;
    }
    /**
     * <pre>
     * Timestamp when this Menu or any of its contents was last updated by the
     * restaurant; i.e. a date to be associated with the phrase “accurate as of
     * date”.
     * Optional.
     * </pre>
     *
     * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
     * @return The lastMerchantUpdateTime.
     */
    @java.lang.Override
    public com.google.protobuf.Timestamp getLastMerchantUpdateTime() {
      return lastMerchantUpdateTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastMerchantUpdateTime_;
    }
    /**
     * <pre>
     * Timestamp when this Menu or any of its contents was last updated by the
     * restaurant; i.e. a date to be associated with the phrase “accurate as of
     * date”.
     * Optional.
     * </pre>
     *
     * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
     */
    @java.lang.Override
    public com.google.protobuf.TimestampOrBuilder getLastMerchantUpdateTimeOrBuilder() {
      return lastMerchantUpdateTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastMerchantUpdateTime_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(menuId_)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, menuId_);
      }
      for (int i = 0; i < merchantIds_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, merchantIds_.getRaw(i));
      }
      if (displayName_ != null) {
        output.writeMessage(3, getDisplayName());
      }
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(language_)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, language_);
      }
      if (disclaimer_ != null) {
        output.writeMessage(5, getDisclaimer());
      }
      for (int i = 0; i < menuItemIds_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, menuItemIds_.getRaw(i));
      }
      for (int i = 0; i < menuSectionIds_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 7, menuSectionIds_.getRaw(i));
      }
      if (lastMerchantUpdateTime_ != null) {
        output.writeMessage(8, getLastMerchantUpdateTime());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(menuId_)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, menuId_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < merchantIds_.size(); i++) {
          dataSize += computeStringSizeNoTag(merchantIds_.getRaw(i));
        }
        size += dataSize;
        size += 1 * getMerchantIdsList().size();
      }
      if (displayName_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getDisplayName());
      }
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(language_)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, language_);
      }
      if (disclaimer_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(5, getDisclaimer());
      }
      {
        int dataSize = 0;
        for (int i = 0; i < menuItemIds_.size(); i++) {
          dataSize += computeStringSizeNoTag(menuItemIds_.getRaw(i));
        }
        size += dataSize;
        size += 1 * getMenuItemIdsList().size();
      }
      {
        int dataSize = 0;
        for (int i = 0; i < menuSectionIds_.size(); i++) {
          dataSize += computeStringSizeNoTag(menuSectionIds_.getRaw(i));
        }
        size += dataSize;
        size += 1 * getMenuSectionIdsList().size();
      }
      if (lastMerchantUpdateTime_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(8, getLastMerchantUpdateTime());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.Menu)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.Menu other = (food.menu.v1.FoodMenu.Menu) obj;

      if (!getMenuId()
          .equals(other.getMenuId())) return false;
      if (!getMerchantIdsList()
          .equals(other.getMerchantIdsList())) return false;
      if (hasDisplayName() != other.hasDisplayName()) return false;
      if (hasDisplayName()) {
        if (!getDisplayName()
            .equals(other.getDisplayName())) return false;
      }
      if (!getLanguage()
          .equals(other.getLanguage())) return false;
      if (hasDisclaimer() != other.hasDisclaimer()) return false;
      if (hasDisclaimer()) {
        if (!getDisclaimer()
            .equals(other.getDisclaimer())) return false;
      }
      if (!getMenuItemIdsList()
          .equals(other.getMenuItemIdsList())) return false;
      if (!getMenuSectionIdsList()
          .equals(other.getMenuSectionIdsList())) return false;
      if (hasLastMerchantUpdateTime() != other.hasLastMerchantUpdateTime()) return false;
      if (hasLastMerchantUpdateTime()) {
        if (!getLastMerchantUpdateTime()
            .equals(other.getLastMerchantUpdateTime())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      hash = (37 * hash) + MENU_ID_FIELD_NUMBER;
      hash = (53 * hash) + getMenuId().hashCode();
      if (getMerchantIdsCount() > 0) {
        hash = (37 * hash) + MERCHANT_IDS_FIELD_NUMBER;
        hash = (53 * hash) + getMerchantIdsList().hashCode();
      }
      if (hasDisplayName()) {
        hash = (37 * hash) + DISPLAY_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getDisplayName().hashCode();
      }
      hash = (37 * hash) + LANGUAGE_FIELD_NUMBER;
      hash = (53 * hash) + getLanguage().hashCode();
      if (hasDisclaimer()) {
        hash = (37 * hash) + DISCLAIMER_FIELD_NUMBER;
        hash = (53 * hash) + getDisclaimer().hashCode();
      }
      if (getMenuItemIdsCount() > 0) {
        hash = (37 * hash) + MENU_ITEM_IDS_FIELD_NUMBER;
        hash = (53 * hash) + getMenuItemIdsList().hashCode();
      }
      if (getMenuSectionIdsCount() > 0) {
        hash = (37 * hash) + MENU_SECTION_IDS_FIELD_NUMBER;
        hash = (53 * hash) + getMenuSectionIdsList().hashCode();
      }
      if (hasLastMerchantUpdateTime()) {
        hash = (37 * hash) + LAST_MERCHANT_UPDATE_TIME_FIELD_NUMBER;
        hash = (53 * hash) + getLastMerchantUpdateTime().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.Menu parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Menu parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Menu parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Menu parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Menu parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Menu parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Menu parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Menu parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Menu parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Menu parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Menu parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Menu parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.Menu prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Top-level catalog of food items offered by a Food establishment. Menu
     * contains a list of merchant ids and the menu that apply to those merchants.
     * A Menu can be used to represent single merchant with the menu, or multiple
     * merchants (typically chain restaurants) with the menus.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.Menu}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.Menu)
        food.menu.v1.FoodMenu.MenuOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Menu_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Menu_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.Menu.class, food.menu.v1.FoodMenu.Menu.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.Menu.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        menuId_ = "";
        merchantIds_ =
            com.google.protobuf.LazyStringArrayList.emptyList();
        displayName_ = null;
        if (displayNameBuilder_ != null) {
          displayNameBuilder_.dispose();
          displayNameBuilder_ = null;
        }
        language_ = "";
        disclaimer_ = null;
        if (disclaimerBuilder_ != null) {
          disclaimerBuilder_.dispose();
          disclaimerBuilder_ = null;
        }
        menuItemIds_ =
            com.google.protobuf.LazyStringArrayList.emptyList();
        menuSectionIds_ =
            com.google.protobuf.LazyStringArrayList.emptyList();
        lastMerchantUpdateTime_ = null;
        if (lastMerchantUpdateTimeBuilder_ != null) {
          lastMerchantUpdateTimeBuilder_.dispose();
          lastMerchantUpdateTimeBuilder_ = null;
        }
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Menu_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Menu getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.Menu.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Menu build() {
        food.menu.v1.FoodMenu.Menu result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Menu buildPartial() {
        food.menu.v1.FoodMenu.Menu result = new food.menu.v1.FoodMenu.Menu(this);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartial0(food.menu.v1.FoodMenu.Menu result) {
        int from_bitField0_ = bitField0_;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.menuId_ = menuId_;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          merchantIds_.makeImmutable();
          result.merchantIds_ = merchantIds_;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.displayName_ = displayNameBuilder_ == null
              ? displayName_
              : displayNameBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.language_ = language_;
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.disclaimer_ = disclaimerBuilder_ == null
              ? disclaimer_
              : disclaimerBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          menuItemIds_.makeImmutable();
          result.menuItemIds_ = menuItemIds_;
        }
        if (((from_bitField0_ & 0x00000040) != 0)) {
          menuSectionIds_.makeImmutable();
          result.menuSectionIds_ = menuSectionIds_;
        }
        if (((from_bitField0_ & 0x00000080) != 0)) {
          result.lastMerchantUpdateTime_ = lastMerchantUpdateTimeBuilder_ == null
              ? lastMerchantUpdateTime_
              : lastMerchantUpdateTimeBuilder_.build();
        }
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.Menu) {
          return mergeFrom((food.menu.v1.FoodMenu.Menu)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.Menu other) {
        if (other == food.menu.v1.FoodMenu.Menu.getDefaultInstance()) return this;
        if (!other.getMenuId().isEmpty()) {
          menuId_ = other.menuId_;
          bitField0_ |= 0x00000001;
          onChanged();
        }
        if (!other.merchantIds_.isEmpty()) {
          if (merchantIds_.isEmpty()) {
            merchantIds_ = other.merchantIds_;
            bitField0_ |= 0x00000002;
          } else {
            ensureMerchantIdsIsMutable();
            merchantIds_.addAll(other.merchantIds_);
          }
          onChanged();
        }
        if (other.hasDisplayName()) {
          mergeDisplayName(other.getDisplayName());
        }
        if (!other.getLanguage().isEmpty()) {
          language_ = other.language_;
          bitField0_ |= 0x00000008;
          onChanged();
        }
        if (other.hasDisclaimer()) {
          mergeDisclaimer(other.getDisclaimer());
        }
        if (!other.menuItemIds_.isEmpty()) {
          if (menuItemIds_.isEmpty()) {
            menuItemIds_ = other.menuItemIds_;
            bitField0_ |= 0x00000020;
          } else {
            ensureMenuItemIdsIsMutable();
            menuItemIds_.addAll(other.menuItemIds_);
          }
          onChanged();
        }
        if (!other.menuSectionIds_.isEmpty()) {
          if (menuSectionIds_.isEmpty()) {
            menuSectionIds_ = other.menuSectionIds_;
            bitField0_ |= 0x00000040;
          } else {
            ensureMenuSectionIdsIsMutable();
            menuSectionIds_.addAll(other.menuSectionIds_);
          }
          onChanged();
        }
        if (other.hasLastMerchantUpdateTime()) {
          mergeLastMerchantUpdateTime(other.getLastMerchantUpdateTime());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                menuId_ = input.readStringRequireUtf8();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                java.lang.String s = input.readStringRequireUtf8();
                ensureMerchantIdsIsMutable();
                merchantIds_.add(s);
                break;
              } // case 18
              case 26: {
                input.readMessage(
                    getDisplayNameFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              case 34: {
                language_ = input.readStringRequireUtf8();
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              case 42: {
                input.readMessage(
                    getDisclaimerFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000010;
                break;
              } // case 42
              case 50: {
                java.lang.String s = input.readStringRequireUtf8();
                ensureMenuItemIdsIsMutable();
                menuItemIds_.add(s);
                break;
              } // case 50
              case 58: {
                java.lang.String s = input.readStringRequireUtf8();
                ensureMenuSectionIdsIsMutable();
                menuSectionIds_.add(s);
                break;
              } // case 58
              case 66: {
                input.readMessage(
                    getLastMerchantUpdateTimeFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000080;
                break;
              } // case 66
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object menuId_ = "";
      /**
       * <pre>
       * An opaque string from a partner which uniquely identifies the Menu within
       * the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_id = 1;</code>
       * @return The menuId.
       */
      public java.lang.String getMenuId() {
        java.lang.Object ref = menuId_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          menuId_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * An opaque string from a partner which uniquely identifies the Menu within
       * the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_id = 1;</code>
       * @return The bytes for menuId.
       */
      public com.google.protobuf.ByteString
          getMenuIdBytes() {
        java.lang.Object ref = menuId_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          menuId_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * An opaque string from a partner which uniquely identifies the Menu within
       * the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_id = 1;</code>
       * @param value The menuId to set.
       * @return This builder for chaining.
       */
      public Builder setMenuId(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        menuId_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * An opaque string from a partner which uniquely identifies the Menu within
       * the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_id = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearMenuId() {
        menuId_ = getDefaultInstance().getMenuId();
        bitField0_ = (bitField0_ & ~0x00000001);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * An opaque string from a partner which uniquely identifies the Menu within
       * the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_id = 1;</code>
       * @param value The bytes for menuId to set.
       * @return This builder for chaining.
       */
      public Builder setMenuIdBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        menuId_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }

      private com.google.protobuf.LazyStringArrayList merchantIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
      private void ensureMerchantIdsIsMutable() {
        if (!merchantIds_.isModifiable()) {
          merchantIds_ = new com.google.protobuf.LazyStringArrayList(merchantIds_);
        }
        bitField0_ |= 0x00000002;
      }
      /**
       * <pre>
       * The merchants to whom the menu apply.
       * Note: This field is repeated so chain restaurants can share the same menu
       * across multiple locations, each of which is a separate merchant.
       * Required.
       * </pre>
       *
       * <code>repeated string merchant_ids = 2;</code>
       * @return A list containing the merchantIds.
       */
      public com.google.protobuf.ProtocolStringList
          getMerchantIdsList() {
        merchantIds_.makeImmutable();
        return merchantIds_;
      }
      /**
       * <pre>
       * The merchants to whom the menu apply.
       * Note: This field is repeated so chain restaurants can share the same menu
       * across multiple locations, each of which is a separate merchant.
       * Required.
       * </pre>
       *
       * <code>repeated string merchant_ids = 2;</code>
       * @return The count of merchantIds.
       */
      public int getMerchantIdsCount() {
        return merchantIds_.size();
      }
      /**
       * <pre>
       * The merchants to whom the menu apply.
       * Note: This field is repeated so chain restaurants can share the same menu
       * across multiple locations, each of which is a separate merchant.
       * Required.
       * </pre>
       *
       * <code>repeated string merchant_ids = 2;</code>
       * @param index The index of the element to return.
       * @return The merchantIds at the given index.
       */
      public java.lang.String getMerchantIds(int index) {
        return merchantIds_.get(index);
      }
      /**
       * <pre>
       * The merchants to whom the menu apply.
       * Note: This field is repeated so chain restaurants can share the same menu
       * across multiple locations, each of which is a separate merchant.
       * Required.
       * </pre>
       *
       * <code>repeated string merchant_ids = 2;</code>
       * @param index The index of the value to return.
       * @return The bytes of the merchantIds at the given index.
       */
      public com.google.protobuf.ByteString
          getMerchantIdsBytes(int index) {
        return merchantIds_.getByteString(index);
      }
      /**
       * <pre>
       * The merchants to whom the menu apply.
       * Note: This field is repeated so chain restaurants can share the same menu
       * across multiple locations, each of which is a separate merchant.
       * Required.
       * </pre>
       *
       * <code>repeated string merchant_ids = 2;</code>
       * @param index The index to set the value at.
       * @param value The merchantIds to set.
       * @return This builder for chaining.
       */
      public Builder setMerchantIds(
          int index, java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        ensureMerchantIdsIsMutable();
        merchantIds_.set(index, value);
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The merchants to whom the menu apply.
       * Note: This field is repeated so chain restaurants can share the same menu
       * across multiple locations, each of which is a separate merchant.
       * Required.
       * </pre>
       *
       * <code>repeated string merchant_ids = 2;</code>
       * @param value The merchantIds to add.
       * @return This builder for chaining.
       */
      public Builder addMerchantIds(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        ensureMerchantIdsIsMutable();
        merchantIds_.add(value);
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The merchants to whom the menu apply.
       * Note: This field is repeated so chain restaurants can share the same menu
       * across multiple locations, each of which is a separate merchant.
       * Required.
       * </pre>
       *
       * <code>repeated string merchant_ids = 2;</code>
       * @param values The merchantIds to add.
       * @return This builder for chaining.
       */
      public Builder addAllMerchantIds(
          java.lang.Iterable<java.lang.String> values) {
        ensureMerchantIdsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, merchantIds_);
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The merchants to whom the menu apply.
       * Note: This field is repeated so chain restaurants can share the same menu
       * across multiple locations, each of which is a separate merchant.
       * Required.
       * </pre>
       *
       * <code>repeated string merchant_ids = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearMerchantIds() {
        merchantIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
        bitField0_ = (bitField0_ & ~0x00000002);;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The merchants to whom the menu apply.
       * Note: This field is repeated so chain restaurants can share the same menu
       * across multiple locations, each of which is a separate merchant.
       * Required.
       * </pre>
       *
       * <code>repeated string merchant_ids = 2;</code>
       * @param value The bytes of the merchantIds to add.
       * @return This builder for chaining.
       */
      public Builder addMerchantIdsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        ensureMerchantIdsIsMutable();
        merchantIds_.add(value);
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }

      private food.menu.v1.FoodMenu.TextField displayName_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> displayNameBuilder_;
      /**
       * <pre>
       * The name that can identify the Menu when a user is browsing the menu.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 3;</code>
       * @return Whether the displayName field is set.
       */
      public boolean hasDisplayName() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <pre>
       * The name that can identify the Menu when a user is browsing the menu.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 3;</code>
       * @return The displayName.
       */
      public food.menu.v1.FoodMenu.TextField getDisplayName() {
        if (displayNameBuilder_ == null) {
          return displayName_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : displayName_;
        } else {
          return displayNameBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * The name that can identify the Menu when a user is browsing the menu.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 3;</code>
       */
      public Builder setDisplayName(food.menu.v1.FoodMenu.TextField value) {
        if (displayNameBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          displayName_ = value;
        } else {
          displayNameBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name that can identify the Menu when a user is browsing the menu.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 3;</code>
       */
      public Builder setDisplayName(
          food.menu.v1.FoodMenu.TextField.Builder builderForValue) {
        if (displayNameBuilder_ == null) {
          displayName_ = builderForValue.build();
        } else {
          displayNameBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name that can identify the Menu when a user is browsing the menu.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 3;</code>
       */
      public Builder mergeDisplayName(food.menu.v1.FoodMenu.TextField value) {
        if (displayNameBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
            displayName_ != null &&
            displayName_ != food.menu.v1.FoodMenu.TextField.getDefaultInstance()) {
            getDisplayNameBuilder().mergeFrom(value);
          } else {
            displayName_ = value;
          }
        } else {
          displayNameBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name that can identify the Menu when a user is browsing the menu.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 3;</code>
       */
      public Builder clearDisplayName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        displayName_ = null;
        if (displayNameBuilder_ != null) {
          displayNameBuilder_.dispose();
          displayNameBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name that can identify the Menu when a user is browsing the menu.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 3;</code>
       */
      public food.menu.v1.FoodMenu.TextField.Builder getDisplayNameBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getDisplayNameFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * The name that can identify the Menu when a user is browsing the menu.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 3;</code>
       */
      public food.menu.v1.FoodMenu.TextFieldOrBuilder getDisplayNameOrBuilder() {
        if (displayNameBuilder_ != null) {
          return displayNameBuilder_.getMessageOrBuilder();
        } else {
          return displayName_ == null ?
              food.menu.v1.FoodMenu.TextField.getDefaultInstance() : displayName_;
        }
      }
      /**
       * <pre>
       * The name that can identify the Menu when a user is browsing the menu.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> 
          getDisplayNameFieldBuilder() {
        if (displayNameBuilder_ == null) {
          displayNameBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder>(
                  getDisplayName(),
                  getParentForChildren(),
                  isClean());
          displayName_ = null;
        }
        return displayNameBuilder_;
      }

      private java.lang.Object language_ = "";
      /**
       * <pre>
       * The default language code associated with the text labels contained in the
       * menu. Expects BCP-47 language code, such as "en-US" or "sr-Latn".
       *
       * For more information, see
       * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
       * Optional.
       * </pre>
       *
       * <code>string language = 4;</code>
       * @return The language.
       */
      public java.lang.String getLanguage() {
        java.lang.Object ref = language_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          language_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * The default language code associated with the text labels contained in the
       * menu. Expects BCP-47 language code, such as "en-US" or "sr-Latn".
       *
       * For more information, see
       * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
       * Optional.
       * </pre>
       *
       * <code>string language = 4;</code>
       * @return The bytes for language.
       */
      public com.google.protobuf.ByteString
          getLanguageBytes() {
        java.lang.Object ref = language_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          language_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * The default language code associated with the text labels contained in the
       * menu. Expects BCP-47 language code, such as "en-US" or "sr-Latn".
       *
       * For more information, see
       * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
       * Optional.
       * </pre>
       *
       * <code>string language = 4;</code>
       * @param value The language to set.
       * @return This builder for chaining.
       */
      public Builder setLanguage(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        language_ = value;
        bitField0_ |= 0x00000008;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The default language code associated with the text labels contained in the
       * menu. Expects BCP-47 language code, such as "en-US" or "sr-Latn".
       *
       * For more information, see
       * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
       * Optional.
       * </pre>
       *
       * <code>string language = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearLanguage() {
        language_ = getDefaultInstance().getLanguage();
        bitField0_ = (bitField0_ & ~0x00000008);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The default language code associated with the text labels contained in the
       * menu. Expects BCP-47 language code, such as "en-US" or "sr-Latn".
       *
       * For more information, see
       * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
       * Optional.
       * </pre>
       *
       * <code>string language = 4;</code>
       * @param value The bytes for language to set.
       * @return This builder for chaining.
       */
      public Builder setLanguageBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        language_ = value;
        bitField0_ |= 0x00000008;
        onChanged();
        return this;
      }

      private food.menu.v1.FoodMenu.Disclaimer disclaimer_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.Disclaimer, food.menu.v1.FoodMenu.Disclaimer.Builder, food.menu.v1.FoodMenu.DisclaimerOrBuilder> disclaimerBuilder_;
      /**
       * <pre>
       * Disclaimer to be shown to the user for the menu. For example, nutritional
       * information disclosure and allergen disclosure.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
       * @return Whether the disclaimer field is set.
       */
      public boolean hasDisclaimer() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <pre>
       * Disclaimer to be shown to the user for the menu. For example, nutritional
       * information disclosure and allergen disclosure.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
       * @return The disclaimer.
       */
      public food.menu.v1.FoodMenu.Disclaimer getDisclaimer() {
        if (disclaimerBuilder_ == null) {
          return disclaimer_ == null ? food.menu.v1.FoodMenu.Disclaimer.getDefaultInstance() : disclaimer_;
        } else {
          return disclaimerBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Disclaimer to be shown to the user for the menu. For example, nutritional
       * information disclosure and allergen disclosure.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
       */
      public Builder setDisclaimer(food.menu.v1.FoodMenu.Disclaimer value) {
        if (disclaimerBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          disclaimer_ = value;
        } else {
          disclaimerBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000010;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Disclaimer to be shown to the user for the menu. For example, nutritional
       * information disclosure and allergen disclosure.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
       */
      public Builder setDisclaimer(
          food.menu.v1.FoodMenu.Disclaimer.Builder builderForValue) {
        if (disclaimerBuilder_ == null) {
          disclaimer_ = builderForValue.build();
        } else {
          disclaimerBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000010;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Disclaimer to be shown to the user for the menu. For example, nutritional
       * information disclosure and allergen disclosure.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
       */
      public Builder mergeDisclaimer(food.menu.v1.FoodMenu.Disclaimer value) {
        if (disclaimerBuilder_ == null) {
          if (((bitField0_ & 0x00000010) != 0) &&
            disclaimer_ != null &&
            disclaimer_ != food.menu.v1.FoodMenu.Disclaimer.getDefaultInstance()) {
            getDisclaimerBuilder().mergeFrom(value);
          } else {
            disclaimer_ = value;
          }
        } else {
          disclaimerBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000010;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Disclaimer to be shown to the user for the menu. For example, nutritional
       * information disclosure and allergen disclosure.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
       */
      public Builder clearDisclaimer() {
        bitField0_ = (bitField0_ & ~0x00000010);
        disclaimer_ = null;
        if (disclaimerBuilder_ != null) {
          disclaimerBuilder_.dispose();
          disclaimerBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Disclaimer to be shown to the user for the menu. For example, nutritional
       * information disclosure and allergen disclosure.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
       */
      public food.menu.v1.FoodMenu.Disclaimer.Builder getDisclaimerBuilder() {
        bitField0_ |= 0x00000010;
        onChanged();
        return getDisclaimerFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Disclaimer to be shown to the user for the menu. For example, nutritional
       * information disclosure and allergen disclosure.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
       */
      public food.menu.v1.FoodMenu.DisclaimerOrBuilder getDisclaimerOrBuilder() {
        if (disclaimerBuilder_ != null) {
          return disclaimerBuilder_.getMessageOrBuilder();
        } else {
          return disclaimer_ == null ?
              food.menu.v1.FoodMenu.Disclaimer.getDefaultInstance() : disclaimer_;
        }
      }
      /**
       * <pre>
       * Disclaimer to be shown to the user for the menu. For example, nutritional
       * information disclosure and allergen disclosure.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.Disclaimer disclaimer = 5;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.Disclaimer, food.menu.v1.FoodMenu.Disclaimer.Builder, food.menu.v1.FoodMenu.DisclaimerOrBuilder> 
          getDisclaimerFieldBuilder() {
        if (disclaimerBuilder_ == null) {
          disclaimerBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.Disclaimer, food.menu.v1.FoodMenu.Disclaimer.Builder, food.menu.v1.FoodMenu.DisclaimerOrBuilder>(
                  getDisclaimer(),
                  getParentForChildren(),
                  isClean());
          disclaimer_ = null;
        }
        return disclaimerBuilder_;
      }

      private com.google.protobuf.LazyStringArrayList menuItemIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
      private void ensureMenuItemIdsIsMutable() {
        if (!menuItemIds_.isModifiable()) {
          menuItemIds_ = new com.google.protobuf.LazyStringArrayList(menuItemIds_);
        }
        bitField0_ |= 0x00000020;
      }
      /**
       * <pre>
       * IDs of items contained within this menu. Expects first-level menu items
       * only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @return A list containing the menuItemIds.
       */
      public com.google.protobuf.ProtocolStringList
          getMenuItemIdsList() {
        menuItemIds_.makeImmutable();
        return menuItemIds_;
      }
      /**
       * <pre>
       * IDs of items contained within this menu. Expects first-level menu items
       * only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @return The count of menuItemIds.
       */
      public int getMenuItemIdsCount() {
        return menuItemIds_.size();
      }
      /**
       * <pre>
       * IDs of items contained within this menu. Expects first-level menu items
       * only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @param index The index of the element to return.
       * @return The menuItemIds at the given index.
       */
      public java.lang.String getMenuItemIds(int index) {
        return menuItemIds_.get(index);
      }
      /**
       * <pre>
       * IDs of items contained within this menu. Expects first-level menu items
       * only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @param index The index of the value to return.
       * @return The bytes of the menuItemIds at the given index.
       */
      public com.google.protobuf.ByteString
          getMenuItemIdsBytes(int index) {
        return menuItemIds_.getByteString(index);
      }
      /**
       * <pre>
       * IDs of items contained within this menu. Expects first-level menu items
       * only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @param index The index to set the value at.
       * @param value The menuItemIds to set.
       * @return This builder for chaining.
       */
      public Builder setMenuItemIds(
          int index, java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        ensureMenuItemIdsIsMutable();
        menuItemIds_.set(index, value);
        bitField0_ |= 0x00000020;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * IDs of items contained within this menu. Expects first-level menu items
       * only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @param value The menuItemIds to add.
       * @return This builder for chaining.
       */
      public Builder addMenuItemIds(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        ensureMenuItemIdsIsMutable();
        menuItemIds_.add(value);
        bitField0_ |= 0x00000020;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * IDs of items contained within this menu. Expects first-level menu items
       * only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @param values The menuItemIds to add.
       * @return This builder for chaining.
       */
      public Builder addAllMenuItemIds(
          java.lang.Iterable<java.lang.String> values) {
        ensureMenuItemIdsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, menuItemIds_);
        bitField0_ |= 0x00000020;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * IDs of items contained within this menu. Expects first-level menu items
       * only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearMenuItemIds() {
        menuItemIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
        bitField0_ = (bitField0_ & ~0x00000020);;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * IDs of items contained within this menu. Expects first-level menu items
       * only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @param value The bytes of the menuItemIds to add.
       * @return This builder for chaining.
       */
      public Builder addMenuItemIdsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        ensureMenuItemIdsIsMutable();
        menuItemIds_.add(value);
        bitField0_ |= 0x00000020;
        onChanged();
        return this;
      }

      private com.google.protobuf.LazyStringArrayList menuSectionIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
      private void ensureMenuSectionIdsIsMutable() {
        if (!menuSectionIds_.isModifiable()) {
          menuSectionIds_ = new com.google.protobuf.LazyStringArrayList(menuSectionIds_);
        }
        bitField0_ |= 0x00000040;
      }
      /**
       * <pre>
       * IDs of sections contained within this menu. Expects first-level menu
       * sections only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @return A list containing the menuSectionIds.
       */
      public com.google.protobuf.ProtocolStringList
          getMenuSectionIdsList() {
        menuSectionIds_.makeImmutable();
        return menuSectionIds_;
      }
      /**
       * <pre>
       * IDs of sections contained within this menu. Expects first-level menu
       * sections only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @return The count of menuSectionIds.
       */
      public int getMenuSectionIdsCount() {
        return menuSectionIds_.size();
      }
      /**
       * <pre>
       * IDs of sections contained within this menu. Expects first-level menu
       * sections only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @param index The index of the element to return.
       * @return The menuSectionIds at the given index.
       */
      public java.lang.String getMenuSectionIds(int index) {
        return menuSectionIds_.get(index);
      }
      /**
       * <pre>
       * IDs of sections contained within this menu. Expects first-level menu
       * sections only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @param index The index of the value to return.
       * @return The bytes of the menuSectionIds at the given index.
       */
      public com.google.protobuf.ByteString
          getMenuSectionIdsBytes(int index) {
        return menuSectionIds_.getByteString(index);
      }
      /**
       * <pre>
       * IDs of sections contained within this menu. Expects first-level menu
       * sections only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @param index The index to set the value at.
       * @param value The menuSectionIds to set.
       * @return This builder for chaining.
       */
      public Builder setMenuSectionIds(
          int index, java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        ensureMenuSectionIdsIsMutable();
        menuSectionIds_.set(index, value);
        bitField0_ |= 0x00000040;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * IDs of sections contained within this menu. Expects first-level menu
       * sections only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @param value The menuSectionIds to add.
       * @return This builder for chaining.
       */
      public Builder addMenuSectionIds(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        ensureMenuSectionIdsIsMutable();
        menuSectionIds_.add(value);
        bitField0_ |= 0x00000040;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * IDs of sections contained within this menu. Expects first-level menu
       * sections only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @param values The menuSectionIds to add.
       * @return This builder for chaining.
       */
      public Builder addAllMenuSectionIds(
          java.lang.Iterable<java.lang.String> values) {
        ensureMenuSectionIdsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, menuSectionIds_);
        bitField0_ |= 0x00000040;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * IDs of sections contained within this menu. Expects first-level menu
       * sections only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearMenuSectionIds() {
        menuSectionIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
        bitField0_ = (bitField0_ & ~0x00000040);;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * IDs of sections contained within this menu. Expects first-level menu
       * sections only.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @param value The bytes of the menuSectionIds to add.
       * @return This builder for chaining.
       */
      public Builder addMenuSectionIdsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        ensureMenuSectionIdsIsMutable();
        menuSectionIds_.add(value);
        bitField0_ |= 0x00000040;
        onChanged();
        return this;
      }

      private com.google.protobuf.Timestamp lastMerchantUpdateTime_;
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> lastMerchantUpdateTimeBuilder_;
      /**
       * <pre>
       * Timestamp when this Menu or any of its contents was last updated by the
       * restaurant; i.e. a date to be associated with the phrase “accurate as of
       * date”.
       * Optional.
       * </pre>
       *
       * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
       * @return Whether the lastMerchantUpdateTime field is set.
       */
      public boolean hasLastMerchantUpdateTime() {
        return ((bitField0_ & 0x00000080) != 0);
      }
      /**
       * <pre>
       * Timestamp when this Menu or any of its contents was last updated by the
       * restaurant; i.e. a date to be associated with the phrase “accurate as of
       * date”.
       * Optional.
       * </pre>
       *
       * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
       * @return The lastMerchantUpdateTime.
       */
      public com.google.protobuf.Timestamp getLastMerchantUpdateTime() {
        if (lastMerchantUpdateTimeBuilder_ == null) {
          return lastMerchantUpdateTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastMerchantUpdateTime_;
        } else {
          return lastMerchantUpdateTimeBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Timestamp when this Menu or any of its contents was last updated by the
       * restaurant; i.e. a date to be associated with the phrase “accurate as of
       * date”.
       * Optional.
       * </pre>
       *
       * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
       */
      public Builder setLastMerchantUpdateTime(com.google.protobuf.Timestamp value) {
        if (lastMerchantUpdateTimeBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          lastMerchantUpdateTime_ = value;
        } else {
          lastMerchantUpdateTimeBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000080;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Timestamp when this Menu or any of its contents was last updated by the
       * restaurant; i.e. a date to be associated with the phrase “accurate as of
       * date”.
       * Optional.
       * </pre>
       *
       * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
       */
      public Builder setLastMerchantUpdateTime(
          com.google.protobuf.Timestamp.Builder builderForValue) {
        if (lastMerchantUpdateTimeBuilder_ == null) {
          lastMerchantUpdateTime_ = builderForValue.build();
        } else {
          lastMerchantUpdateTimeBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000080;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Timestamp when this Menu or any of its contents was last updated by the
       * restaurant; i.e. a date to be associated with the phrase “accurate as of
       * date”.
       * Optional.
       * </pre>
       *
       * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
       */
      public Builder mergeLastMerchantUpdateTime(com.google.protobuf.Timestamp value) {
        if (lastMerchantUpdateTimeBuilder_ == null) {
          if (((bitField0_ & 0x00000080) != 0) &&
            lastMerchantUpdateTime_ != null &&
            lastMerchantUpdateTime_ != com.google.protobuf.Timestamp.getDefaultInstance()) {
            getLastMerchantUpdateTimeBuilder().mergeFrom(value);
          } else {
            lastMerchantUpdateTime_ = value;
          }
        } else {
          lastMerchantUpdateTimeBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000080;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Timestamp when this Menu or any of its contents was last updated by the
       * restaurant; i.e. a date to be associated with the phrase “accurate as of
       * date”.
       * Optional.
       * </pre>
       *
       * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
       */
      public Builder clearLastMerchantUpdateTime() {
        bitField0_ = (bitField0_ & ~0x00000080);
        lastMerchantUpdateTime_ = null;
        if (lastMerchantUpdateTimeBuilder_ != null) {
          lastMerchantUpdateTimeBuilder_.dispose();
          lastMerchantUpdateTimeBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Timestamp when this Menu or any of its contents was last updated by the
       * restaurant; i.e. a date to be associated with the phrase “accurate as of
       * date”.
       * Optional.
       * </pre>
       *
       * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
       */
      public com.google.protobuf.Timestamp.Builder getLastMerchantUpdateTimeBuilder() {
        bitField0_ |= 0x00000080;
        onChanged();
        return getLastMerchantUpdateTimeFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Timestamp when this Menu or any of its contents was last updated by the
       * restaurant; i.e. a date to be associated with the phrase “accurate as of
       * date”.
       * Optional.
       * </pre>
       *
       * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
       */
      public com.google.protobuf.TimestampOrBuilder getLastMerchantUpdateTimeOrBuilder() {
        if (lastMerchantUpdateTimeBuilder_ != null) {
          return lastMerchantUpdateTimeBuilder_.getMessageOrBuilder();
        } else {
          return lastMerchantUpdateTime_ == null ?
              com.google.protobuf.Timestamp.getDefaultInstance() : lastMerchantUpdateTime_;
        }
      }
      /**
       * <pre>
       * Timestamp when this Menu or any of its contents was last updated by the
       * restaurant; i.e. a date to be associated with the phrase “accurate as of
       * date”.
       * Optional.
       * </pre>
       *
       * <code>.google.protobuf.Timestamp last_merchant_update_time = 8;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
          getLastMerchantUpdateTimeFieldBuilder() {
        if (lastMerchantUpdateTimeBuilder_ == null) {
          lastMerchantUpdateTimeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
                  getLastMerchantUpdateTime(),
                  getParentForChildren(),
                  isClean());
          lastMerchantUpdateTime_ = null;
        }
        return lastMerchantUpdateTimeBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.Menu)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.Menu)
    private static final food.menu.v1.FoodMenu.Menu DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.Menu();
    }

    public static food.menu.v1.FoodMenu.Menu getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<Menu>
        PARSER = new com.google.protobuf.AbstractParser<Menu>() {
      @java.lang.Override
      public Menu parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<Menu> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<Menu> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.Menu getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface MenuSectionOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.MenuSection)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * An opaque string from an partner which uniquely identifies the MenuSection
     * within the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_section_id = 1;</code>
     * @return The menuSectionId.
     */
    java.lang.String getMenuSectionId();
    /**
     * <pre>
     * An opaque string from an partner which uniquely identifies the MenuSection
     * within the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_section_id = 1;</code>
     * @return The bytes for menuSectionId.
     */
    com.google.protobuf.ByteString
        getMenuSectionIdBytes();

    /**
     * <pre>
     * The name that can identify the MenuSection when a user is browsing the
     * menu.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 2;</code>
     * @return Whether the displayName field is set.
     */
    boolean hasDisplayName();
    /**
     * <pre>
     * The name that can identify the MenuSection when a user is browsing the
     * menu.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 2;</code>
     * @return The displayName.
     */
    food.menu.v1.FoodMenu.TextField getDisplayName();
    /**
     * <pre>
     * The name that can identify the MenuSection when a user is browsing the
     * menu.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 2;</code>
     */
    food.menu.v1.FoodMenu.TextFieldOrBuilder getDisplayNameOrBuilder();

    /**
     * <pre>
     * A description of the menu section.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 3;</code>
     * @return Whether the description field is set.
     */
    boolean hasDescription();
    /**
     * <pre>
     * A description of the menu section.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 3;</code>
     * @return The description.
     */
    food.menu.v1.FoodMenu.TextField getDescription();
    /**
     * <pre>
     * A description of the menu section.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 3;</code>
     */
    food.menu.v1.FoodMenu.TextFieldOrBuilder getDescriptionOrBuilder();

    /**
     * <pre>
     * Image(s) of the menu section.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    java.util.List<food.menu.v1.FoodMenu.Image> 
        getImagesList();
    /**
     * <pre>
     * Image(s) of the menu section.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    food.menu.v1.FoodMenu.Image getImages(int index);
    /**
     * <pre>
     * Image(s) of the menu section.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    int getImagesCount();
    /**
     * <pre>
     * Image(s) of the menu section.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    java.util.List<? extends food.menu.v1.FoodMenu.ImageOrBuilder> 
        getImagesOrBuilderList();
    /**
     * <pre>
     * Image(s) of the menu section.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    food.menu.v1.FoodMenu.ImageOrBuilder getImagesOrBuilder(
        int index);

    /**
     * <pre>
     * IDs of MenuItem entities that correspond to this MenuSection entity. A
     * section is expected to have at least 1 item if it does not contain any
     * sub-sections.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @return A list containing the menuItemIds.
     */
    java.util.List<java.lang.String>
        getMenuItemIdsList();
    /**
     * <pre>
     * IDs of MenuItem entities that correspond to this MenuSection entity. A
     * section is expected to have at least 1 item if it does not contain any
     * sub-sections.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @return The count of menuItemIds.
     */
    int getMenuItemIdsCount();
    /**
     * <pre>
     * IDs of MenuItem entities that correspond to this MenuSection entity. A
     * section is expected to have at least 1 item if it does not contain any
     * sub-sections.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @param index The index of the element to return.
     * @return The menuItemIds at the given index.
     */
    java.lang.String getMenuItemIds(int index);
    /**
     * <pre>
     * IDs of MenuItem entities that correspond to this MenuSection entity. A
     * section is expected to have at least 1 item if it does not contain any
     * sub-sections.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @param index The index of the value to return.
     * @return The bytes of the menuItemIds at the given index.
     */
    com.google.protobuf.ByteString
        getMenuItemIdsBytes(int index);

    /**
     * <pre>
     * Child MenuSections (sub-sections) that correspond to this MenuSection
     * entity.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @return A list containing the menuSectionIds.
     */
    java.util.List<java.lang.String>
        getMenuSectionIdsList();
    /**
     * <pre>
     * Child MenuSections (sub-sections) that correspond to this MenuSection
     * entity.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @return The count of menuSectionIds.
     */
    int getMenuSectionIdsCount();
    /**
     * <pre>
     * Child MenuSections (sub-sections) that correspond to this MenuSection
     * entity.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @param index The index of the element to return.
     * @return The menuSectionIds at the given index.
     */
    java.lang.String getMenuSectionIds(int index);
    /**
     * <pre>
     * Child MenuSections (sub-sections) that correspond to this MenuSection
     * entity.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @param index The index of the value to return.
     * @return The bytes of the menuSectionIds at the given index.
     */
    com.google.protobuf.ByteString
        getMenuSectionIdsBytes(int index);
  }
  /**
   * <pre>
   * A menu section is a grouping of items on a menu. Separate MenuSections are
   * usually created for each logical grouping of items on a menu. For example,
   * meal course type (Appetizer, Main, Dessert) and food categories (Burgers,
   * Drinks) are typical sections.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.MenuSection}
   */
  public static final class MenuSection extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.MenuSection)
      MenuSectionOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use MenuSection.newBuilder() to construct.
    private MenuSection(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private MenuSection() {
      menuSectionId_ = "";
      images_ = java.util.Collections.emptyList();
      menuItemIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
      menuSectionIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new MenuSection();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuSection_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuSection_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.MenuSection.class, food.menu.v1.FoodMenu.MenuSection.Builder.class);
    }

    public static final int MENU_SECTION_ID_FIELD_NUMBER = 1;
    @SuppressWarnings("serial")
    private volatile java.lang.Object menuSectionId_ = "";
    /**
     * <pre>
     * An opaque string from an partner which uniquely identifies the MenuSection
     * within the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_section_id = 1;</code>
     * @return The menuSectionId.
     */
    @java.lang.Override
    public java.lang.String getMenuSectionId() {
      java.lang.Object ref = menuSectionId_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        menuSectionId_ = s;
        return s;
      }
    }
    /**
     * <pre>
     * An opaque string from an partner which uniquely identifies the MenuSection
     * within the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_section_id = 1;</code>
     * @return The bytes for menuSectionId.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getMenuSectionIdBytes() {
      java.lang.Object ref = menuSectionId_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        menuSectionId_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int DISPLAY_NAME_FIELD_NUMBER = 2;
    private food.menu.v1.FoodMenu.TextField displayName_;
    /**
     * <pre>
     * The name that can identify the MenuSection when a user is browsing the
     * menu.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 2;</code>
     * @return Whether the displayName field is set.
     */
    @java.lang.Override
    public boolean hasDisplayName() {
      return displayName_ != null;
    }
    /**
     * <pre>
     * The name that can identify the MenuSection when a user is browsing the
     * menu.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 2;</code>
     * @return The displayName.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextField getDisplayName() {
      return displayName_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : displayName_;
    }
    /**
     * <pre>
     * The name that can identify the MenuSection when a user is browsing the
     * menu.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 2;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextFieldOrBuilder getDisplayNameOrBuilder() {
      return displayName_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : displayName_;
    }

    public static final int DESCRIPTION_FIELD_NUMBER = 3;
    private food.menu.v1.FoodMenu.TextField description_;
    /**
     * <pre>
     * A description of the menu section.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 3;</code>
     * @return Whether the description field is set.
     */
    @java.lang.Override
    public boolean hasDescription() {
      return description_ != null;
    }
    /**
     * <pre>
     * A description of the menu section.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 3;</code>
     * @return The description.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextField getDescription() {
      return description_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : description_;
    }
    /**
     * <pre>
     * A description of the menu section.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 3;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextFieldOrBuilder getDescriptionOrBuilder() {
      return description_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : description_;
    }

    public static final int IMAGES_FIELD_NUMBER = 4;
    @SuppressWarnings("serial")
    private java.util.List<food.menu.v1.FoodMenu.Image> images_;
    /**
     * <pre>
     * Image(s) of the menu section.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    @java.lang.Override
    public java.util.List<food.menu.v1.FoodMenu.Image> getImagesList() {
      return images_;
    }
    /**
     * <pre>
     * Image(s) of the menu section.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    @java.lang.Override
    public java.util.List<? extends food.menu.v1.FoodMenu.ImageOrBuilder> 
        getImagesOrBuilderList() {
      return images_;
    }
    /**
     * <pre>
     * Image(s) of the menu section.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    @java.lang.Override
    public int getImagesCount() {
      return images_.size();
    }
    /**
     * <pre>
     * Image(s) of the menu section.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.Image getImages(int index) {
      return images_.get(index);
    }
    /**
     * <pre>
     * Image(s) of the menu section.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.ImageOrBuilder getImagesOrBuilder(
        int index) {
      return images_.get(index);
    }

    public static final int MENU_ITEM_IDS_FIELD_NUMBER = 6;
    @SuppressWarnings("serial")
    private com.google.protobuf.LazyStringArrayList menuItemIds_ =
        com.google.protobuf.LazyStringArrayList.emptyList();
    /**
     * <pre>
     * IDs of MenuItem entities that correspond to this MenuSection entity. A
     * section is expected to have at least 1 item if it does not contain any
     * sub-sections.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @return A list containing the menuItemIds.
     */
    public com.google.protobuf.ProtocolStringList
        getMenuItemIdsList() {
      return menuItemIds_;
    }
    /**
     * <pre>
     * IDs of MenuItem entities that correspond to this MenuSection entity. A
     * section is expected to have at least 1 item if it does not contain any
     * sub-sections.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @return The count of menuItemIds.
     */
    public int getMenuItemIdsCount() {
      return menuItemIds_.size();
    }
    /**
     * <pre>
     * IDs of MenuItem entities that correspond to this MenuSection entity. A
     * section is expected to have at least 1 item if it does not contain any
     * sub-sections.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @param index The index of the element to return.
     * @return The menuItemIds at the given index.
     */
    public java.lang.String getMenuItemIds(int index) {
      return menuItemIds_.get(index);
    }
    /**
     * <pre>
     * IDs of MenuItem entities that correspond to this MenuSection entity. A
     * section is expected to have at least 1 item if it does not contain any
     * sub-sections.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_item_ids = 6;</code>
     * @param index The index of the value to return.
     * @return The bytes of the menuItemIds at the given index.
     */
    public com.google.protobuf.ByteString
        getMenuItemIdsBytes(int index) {
      return menuItemIds_.getByteString(index);
    }

    public static final int MENU_SECTION_IDS_FIELD_NUMBER = 7;
    @SuppressWarnings("serial")
    private com.google.protobuf.LazyStringArrayList menuSectionIds_ =
        com.google.protobuf.LazyStringArrayList.emptyList();
    /**
     * <pre>
     * Child MenuSections (sub-sections) that correspond to this MenuSection
     * entity.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @return A list containing the menuSectionIds.
     */
    public com.google.protobuf.ProtocolStringList
        getMenuSectionIdsList() {
      return menuSectionIds_;
    }
    /**
     * <pre>
     * Child MenuSections (sub-sections) that correspond to this MenuSection
     * entity.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @return The count of menuSectionIds.
     */
    public int getMenuSectionIdsCount() {
      return menuSectionIds_.size();
    }
    /**
     * <pre>
     * Child MenuSections (sub-sections) that correspond to this MenuSection
     * entity.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @param index The index of the element to return.
     * @return The menuSectionIds at the given index.
     */
    public java.lang.String getMenuSectionIds(int index) {
      return menuSectionIds_.get(index);
    }
    /**
     * <pre>
     * Child MenuSections (sub-sections) that correspond to this MenuSection
     * entity.
     * Optional.
     * </pre>
     *
     * <code>repeated string menu_section_ids = 7;</code>
     * @param index The index of the value to return.
     * @return The bytes of the menuSectionIds at the given index.
     */
    public com.google.protobuf.ByteString
        getMenuSectionIdsBytes(int index) {
      return menuSectionIds_.getByteString(index);
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(menuSectionId_)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, menuSectionId_);
      }
      if (displayName_ != null) {
        output.writeMessage(2, getDisplayName());
      }
      if (description_ != null) {
        output.writeMessage(3, getDescription());
      }
      for (int i = 0; i < images_.size(); i++) {
        output.writeMessage(4, images_.get(i));
      }
      for (int i = 0; i < menuItemIds_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, menuItemIds_.getRaw(i));
      }
      for (int i = 0; i < menuSectionIds_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 7, menuSectionIds_.getRaw(i));
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(menuSectionId_)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, menuSectionId_);
      }
      if (displayName_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getDisplayName());
      }
      if (description_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getDescription());
      }
      for (int i = 0; i < images_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, images_.get(i));
      }
      {
        int dataSize = 0;
        for (int i = 0; i < menuItemIds_.size(); i++) {
          dataSize += computeStringSizeNoTag(menuItemIds_.getRaw(i));
        }
        size += dataSize;
        size += 1 * getMenuItemIdsList().size();
      }
      {
        int dataSize = 0;
        for (int i = 0; i < menuSectionIds_.size(); i++) {
          dataSize += computeStringSizeNoTag(menuSectionIds_.getRaw(i));
        }
        size += dataSize;
        size += 1 * getMenuSectionIdsList().size();
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.MenuSection)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.MenuSection other = (food.menu.v1.FoodMenu.MenuSection) obj;

      if (!getMenuSectionId()
          .equals(other.getMenuSectionId())) return false;
      if (hasDisplayName() != other.hasDisplayName()) return false;
      if (hasDisplayName()) {
        if (!getDisplayName()
            .equals(other.getDisplayName())) return false;
      }
      if (hasDescription() != other.hasDescription()) return false;
      if (hasDescription()) {
        if (!getDescription()
            .equals(other.getDescription())) return false;
      }
      if (!getImagesList()
          .equals(other.getImagesList())) return false;
      if (!getMenuItemIdsList()
          .equals(other.getMenuItemIdsList())) return false;
      if (!getMenuSectionIdsList()
          .equals(other.getMenuSectionIdsList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      hash = (37 * hash) + MENU_SECTION_ID_FIELD_NUMBER;
      hash = (53 * hash) + getMenuSectionId().hashCode();
      if (hasDisplayName()) {
        hash = (37 * hash) + DISPLAY_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getDisplayName().hashCode();
      }
      if (hasDescription()) {
        hash = (37 * hash) + DESCRIPTION_FIELD_NUMBER;
        hash = (53 * hash) + getDescription().hashCode();
      }
      if (getImagesCount() > 0) {
        hash = (37 * hash) + IMAGES_FIELD_NUMBER;
        hash = (53 * hash) + getImagesList().hashCode();
      }
      if (getMenuItemIdsCount() > 0) {
        hash = (37 * hash) + MENU_ITEM_IDS_FIELD_NUMBER;
        hash = (53 * hash) + getMenuItemIdsList().hashCode();
      }
      if (getMenuSectionIdsCount() > 0) {
        hash = (37 * hash) + MENU_SECTION_IDS_FIELD_NUMBER;
        hash = (53 * hash) + getMenuSectionIdsList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.MenuSection parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuSection parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuSection parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuSection parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuSection parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuSection parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuSection parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuSection parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuSection parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuSection parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuSection parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuSection parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.MenuSection prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * A menu section is a grouping of items on a menu. Separate MenuSections are
     * usually created for each logical grouping of items on a menu. For example,
     * meal course type (Appetizer, Main, Dessert) and food categories (Burgers,
     * Drinks) are typical sections.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.MenuSection}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.MenuSection)
        food.menu.v1.FoodMenu.MenuSectionOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuSection_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuSection_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.MenuSection.class, food.menu.v1.FoodMenu.MenuSection.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.MenuSection.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        menuSectionId_ = "";
        displayName_ = null;
        if (displayNameBuilder_ != null) {
          displayNameBuilder_.dispose();
          displayNameBuilder_ = null;
        }
        description_ = null;
        if (descriptionBuilder_ != null) {
          descriptionBuilder_.dispose();
          descriptionBuilder_ = null;
        }
        if (imagesBuilder_ == null) {
          images_ = java.util.Collections.emptyList();
        } else {
          images_ = null;
          imagesBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        menuItemIds_ =
            com.google.protobuf.LazyStringArrayList.emptyList();
        menuSectionIds_ =
            com.google.protobuf.LazyStringArrayList.emptyList();
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuSection_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuSection getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.MenuSection.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuSection build() {
        food.menu.v1.FoodMenu.MenuSection result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuSection buildPartial() {
        food.menu.v1.FoodMenu.MenuSection result = new food.menu.v1.FoodMenu.MenuSection(this);
        buildPartialRepeatedFields(result);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartialRepeatedFields(food.menu.v1.FoodMenu.MenuSection result) {
        if (imagesBuilder_ == null) {
          if (((bitField0_ & 0x00000008) != 0)) {
            images_ = java.util.Collections.unmodifiableList(images_);
            bitField0_ = (bitField0_ & ~0x00000008);
          }
          result.images_ = images_;
        } else {
          result.images_ = imagesBuilder_.build();
        }
      }

      private void buildPartial0(food.menu.v1.FoodMenu.MenuSection result) {
        int from_bitField0_ = bitField0_;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.menuSectionId_ = menuSectionId_;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.displayName_ = displayNameBuilder_ == null
              ? displayName_
              : displayNameBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.description_ = descriptionBuilder_ == null
              ? description_
              : descriptionBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          menuItemIds_.makeImmutable();
          result.menuItemIds_ = menuItemIds_;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          menuSectionIds_.makeImmutable();
          result.menuSectionIds_ = menuSectionIds_;
        }
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.MenuSection) {
          return mergeFrom((food.menu.v1.FoodMenu.MenuSection)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.MenuSection other) {
        if (other == food.menu.v1.FoodMenu.MenuSection.getDefaultInstance()) return this;
        if (!other.getMenuSectionId().isEmpty()) {
          menuSectionId_ = other.menuSectionId_;
          bitField0_ |= 0x00000001;
          onChanged();
        }
        if (other.hasDisplayName()) {
          mergeDisplayName(other.getDisplayName());
        }
        if (other.hasDescription()) {
          mergeDescription(other.getDescription());
        }
        if (imagesBuilder_ == null) {
          if (!other.images_.isEmpty()) {
            if (images_.isEmpty()) {
              images_ = other.images_;
              bitField0_ = (bitField0_ & ~0x00000008);
            } else {
              ensureImagesIsMutable();
              images_.addAll(other.images_);
            }
            onChanged();
          }
        } else {
          if (!other.images_.isEmpty()) {
            if (imagesBuilder_.isEmpty()) {
              imagesBuilder_.dispose();
              imagesBuilder_ = null;
              images_ = other.images_;
              bitField0_ = (bitField0_ & ~0x00000008);
              imagesBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getImagesFieldBuilder() : null;
            } else {
              imagesBuilder_.addAllMessages(other.images_);
            }
          }
        }
        if (!other.menuItemIds_.isEmpty()) {
          if (menuItemIds_.isEmpty()) {
            menuItemIds_ = other.menuItemIds_;
            bitField0_ |= 0x00000010;
          } else {
            ensureMenuItemIdsIsMutable();
            menuItemIds_.addAll(other.menuItemIds_);
          }
          onChanged();
        }
        if (!other.menuSectionIds_.isEmpty()) {
          if (menuSectionIds_.isEmpty()) {
            menuSectionIds_ = other.menuSectionIds_;
            bitField0_ |= 0x00000020;
          } else {
            ensureMenuSectionIdsIsMutable();
            menuSectionIds_.addAll(other.menuSectionIds_);
          }
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                menuSectionId_ = input.readStringRequireUtf8();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                input.readMessage(
                    getDisplayNameFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                input.readMessage(
                    getDescriptionFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              case 34: {
                food.menu.v1.FoodMenu.Image m =
                    input.readMessage(
                        food.menu.v1.FoodMenu.Image.parser(),
                        extensionRegistry);
                if (imagesBuilder_ == null) {
                  ensureImagesIsMutable();
                  images_.add(m);
                } else {
                  imagesBuilder_.addMessage(m);
                }
                break;
              } // case 34
              case 50: {
                java.lang.String s = input.readStringRequireUtf8();
                ensureMenuItemIdsIsMutable();
                menuItemIds_.add(s);
                break;
              } // case 50
              case 58: {
                java.lang.String s = input.readStringRequireUtf8();
                ensureMenuSectionIdsIsMutable();
                menuSectionIds_.add(s);
                break;
              } // case 58
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object menuSectionId_ = "";
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the MenuSection
       * within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_section_id = 1;</code>
       * @return The menuSectionId.
       */
      public java.lang.String getMenuSectionId() {
        java.lang.Object ref = menuSectionId_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          menuSectionId_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the MenuSection
       * within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_section_id = 1;</code>
       * @return The bytes for menuSectionId.
       */
      public com.google.protobuf.ByteString
          getMenuSectionIdBytes() {
        java.lang.Object ref = menuSectionId_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          menuSectionId_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the MenuSection
       * within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_section_id = 1;</code>
       * @param value The menuSectionId to set.
       * @return This builder for chaining.
       */
      public Builder setMenuSectionId(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        menuSectionId_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the MenuSection
       * within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_section_id = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearMenuSectionId() {
        menuSectionId_ = getDefaultInstance().getMenuSectionId();
        bitField0_ = (bitField0_ & ~0x00000001);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the MenuSection
       * within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_section_id = 1;</code>
       * @param value The bytes for menuSectionId to set.
       * @return This builder for chaining.
       */
      public Builder setMenuSectionIdBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        menuSectionId_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }

      private food.menu.v1.FoodMenu.TextField displayName_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> displayNameBuilder_;
      /**
       * <pre>
       * The name that can identify the MenuSection when a user is browsing the
       * menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       * @return Whether the displayName field is set.
       */
      public boolean hasDisplayName() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * The name that can identify the MenuSection when a user is browsing the
       * menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       * @return The displayName.
       */
      public food.menu.v1.FoodMenu.TextField getDisplayName() {
        if (displayNameBuilder_ == null) {
          return displayName_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : displayName_;
        } else {
          return displayNameBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * The name that can identify the MenuSection when a user is browsing the
       * menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      public Builder setDisplayName(food.menu.v1.FoodMenu.TextField value) {
        if (displayNameBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          displayName_ = value;
        } else {
          displayNameBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name that can identify the MenuSection when a user is browsing the
       * menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      public Builder setDisplayName(
          food.menu.v1.FoodMenu.TextField.Builder builderForValue) {
        if (displayNameBuilder_ == null) {
          displayName_ = builderForValue.build();
        } else {
          displayNameBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name that can identify the MenuSection when a user is browsing the
       * menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      public Builder mergeDisplayName(food.menu.v1.FoodMenu.TextField value) {
        if (displayNameBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
            displayName_ != null &&
            displayName_ != food.menu.v1.FoodMenu.TextField.getDefaultInstance()) {
            getDisplayNameBuilder().mergeFrom(value);
          } else {
            displayName_ = value;
          }
        } else {
          displayNameBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name that can identify the MenuSection when a user is browsing the
       * menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      public Builder clearDisplayName() {
        bitField0_ = (bitField0_ & ~0x00000002);
        displayName_ = null;
        if (displayNameBuilder_ != null) {
          displayNameBuilder_.dispose();
          displayNameBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name that can identify the MenuSection when a user is browsing the
       * menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      public food.menu.v1.FoodMenu.TextField.Builder getDisplayNameBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getDisplayNameFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * The name that can identify the MenuSection when a user is browsing the
       * menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      public food.menu.v1.FoodMenu.TextFieldOrBuilder getDisplayNameOrBuilder() {
        if (displayNameBuilder_ != null) {
          return displayNameBuilder_.getMessageOrBuilder();
        } else {
          return displayName_ == null ?
              food.menu.v1.FoodMenu.TextField.getDefaultInstance() : displayName_;
        }
      }
      /**
       * <pre>
       * The name that can identify the MenuSection when a user is browsing the
       * menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> 
          getDisplayNameFieldBuilder() {
        if (displayNameBuilder_ == null) {
          displayNameBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder>(
                  getDisplayName(),
                  getParentForChildren(),
                  isClean());
          displayName_ = null;
        }
        return displayNameBuilder_;
      }

      private food.menu.v1.FoodMenu.TextField description_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> descriptionBuilder_;
      /**
       * <pre>
       * A description of the menu section.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       * @return Whether the description field is set.
       */
      public boolean hasDescription() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <pre>
       * A description of the menu section.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       * @return The description.
       */
      public food.menu.v1.FoodMenu.TextField getDescription() {
        if (descriptionBuilder_ == null) {
          return description_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : description_;
        } else {
          return descriptionBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * A description of the menu section.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      public Builder setDescription(food.menu.v1.FoodMenu.TextField value) {
        if (descriptionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          description_ = value;
        } else {
          descriptionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * A description of the menu section.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      public Builder setDescription(
          food.menu.v1.FoodMenu.TextField.Builder builderForValue) {
        if (descriptionBuilder_ == null) {
          description_ = builderForValue.build();
        } else {
          descriptionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * A description of the menu section.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      public Builder mergeDescription(food.menu.v1.FoodMenu.TextField value) {
        if (descriptionBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
            description_ != null &&
            description_ != food.menu.v1.FoodMenu.TextField.getDefaultInstance()) {
            getDescriptionBuilder().mergeFrom(value);
          } else {
            description_ = value;
          }
        } else {
          descriptionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * A description of the menu section.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      public Builder clearDescription() {
        bitField0_ = (bitField0_ & ~0x00000004);
        description_ = null;
        if (descriptionBuilder_ != null) {
          descriptionBuilder_.dispose();
          descriptionBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * A description of the menu section.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      public food.menu.v1.FoodMenu.TextField.Builder getDescriptionBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getDescriptionFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * A description of the menu section.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      public food.menu.v1.FoodMenu.TextFieldOrBuilder getDescriptionOrBuilder() {
        if (descriptionBuilder_ != null) {
          return descriptionBuilder_.getMessageOrBuilder();
        } else {
          return description_ == null ?
              food.menu.v1.FoodMenu.TextField.getDefaultInstance() : description_;
        }
      }
      /**
       * <pre>
       * A description of the menu section.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> 
          getDescriptionFieldBuilder() {
        if (descriptionBuilder_ == null) {
          descriptionBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder>(
                  getDescription(),
                  getParentForChildren(),
                  isClean());
          description_ = null;
        }
        return descriptionBuilder_;
      }

      private java.util.List<food.menu.v1.FoodMenu.Image> images_ =
        java.util.Collections.emptyList();
      private void ensureImagesIsMutable() {
        if (!((bitField0_ & 0x00000008) != 0)) {
          images_ = new java.util.ArrayList<food.menu.v1.FoodMenu.Image>(images_);
          bitField0_ |= 0x00000008;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          food.menu.v1.FoodMenu.Image, food.menu.v1.FoodMenu.Image.Builder, food.menu.v1.FoodMenu.ImageOrBuilder> imagesBuilder_;

      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public java.util.List<food.menu.v1.FoodMenu.Image> getImagesList() {
        if (imagesBuilder_ == null) {
          return java.util.Collections.unmodifiableList(images_);
        } else {
          return imagesBuilder_.getMessageList();
        }
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public int getImagesCount() {
        if (imagesBuilder_ == null) {
          return images_.size();
        } else {
          return imagesBuilder_.getCount();
        }
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public food.menu.v1.FoodMenu.Image getImages(int index) {
        if (imagesBuilder_ == null) {
          return images_.get(index);
        } else {
          return imagesBuilder_.getMessage(index);
        }
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder setImages(
          int index, food.menu.v1.FoodMenu.Image value) {
        if (imagesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureImagesIsMutable();
          images_.set(index, value);
          onChanged();
        } else {
          imagesBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder setImages(
          int index, food.menu.v1.FoodMenu.Image.Builder builderForValue) {
        if (imagesBuilder_ == null) {
          ensureImagesIsMutable();
          images_.set(index, builderForValue.build());
          onChanged();
        } else {
          imagesBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder addImages(food.menu.v1.FoodMenu.Image value) {
        if (imagesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureImagesIsMutable();
          images_.add(value);
          onChanged();
        } else {
          imagesBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder addImages(
          int index, food.menu.v1.FoodMenu.Image value) {
        if (imagesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureImagesIsMutable();
          images_.add(index, value);
          onChanged();
        } else {
          imagesBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder addImages(
          food.menu.v1.FoodMenu.Image.Builder builderForValue) {
        if (imagesBuilder_ == null) {
          ensureImagesIsMutable();
          images_.add(builderForValue.build());
          onChanged();
        } else {
          imagesBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder addImages(
          int index, food.menu.v1.FoodMenu.Image.Builder builderForValue) {
        if (imagesBuilder_ == null) {
          ensureImagesIsMutable();
          images_.add(index, builderForValue.build());
          onChanged();
        } else {
          imagesBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder addAllImages(
          java.lang.Iterable<? extends food.menu.v1.FoodMenu.Image> values) {
        if (imagesBuilder_ == null) {
          ensureImagesIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, images_);
          onChanged();
        } else {
          imagesBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder clearImages() {
        if (imagesBuilder_ == null) {
          images_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000008);
          onChanged();
        } else {
          imagesBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder removeImages(int index) {
        if (imagesBuilder_ == null) {
          ensureImagesIsMutable();
          images_.remove(index);
          onChanged();
        } else {
          imagesBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public food.menu.v1.FoodMenu.Image.Builder getImagesBuilder(
          int index) {
        return getImagesFieldBuilder().getBuilder(index);
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public food.menu.v1.FoodMenu.ImageOrBuilder getImagesOrBuilder(
          int index) {
        if (imagesBuilder_ == null) {
          return images_.get(index);  } else {
          return imagesBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public java.util.List<? extends food.menu.v1.FoodMenu.ImageOrBuilder> 
           getImagesOrBuilderList() {
        if (imagesBuilder_ != null) {
          return imagesBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(images_);
        }
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public food.menu.v1.FoodMenu.Image.Builder addImagesBuilder() {
        return getImagesFieldBuilder().addBuilder(
            food.menu.v1.FoodMenu.Image.getDefaultInstance());
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public food.menu.v1.FoodMenu.Image.Builder addImagesBuilder(
          int index) {
        return getImagesFieldBuilder().addBuilder(
            index, food.menu.v1.FoodMenu.Image.getDefaultInstance());
      }
      /**
       * <pre>
       * Image(s) of the menu section.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public java.util.List<food.menu.v1.FoodMenu.Image.Builder> 
           getImagesBuilderList() {
        return getImagesFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          food.menu.v1.FoodMenu.Image, food.menu.v1.FoodMenu.Image.Builder, food.menu.v1.FoodMenu.ImageOrBuilder> 
          getImagesFieldBuilder() {
        if (imagesBuilder_ == null) {
          imagesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              food.menu.v1.FoodMenu.Image, food.menu.v1.FoodMenu.Image.Builder, food.menu.v1.FoodMenu.ImageOrBuilder>(
                  images_,
                  ((bitField0_ & 0x00000008) != 0),
                  getParentForChildren(),
                  isClean());
          images_ = null;
        }
        return imagesBuilder_;
      }

      private com.google.protobuf.LazyStringArrayList menuItemIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
      private void ensureMenuItemIdsIsMutable() {
        if (!menuItemIds_.isModifiable()) {
          menuItemIds_ = new com.google.protobuf.LazyStringArrayList(menuItemIds_);
        }
        bitField0_ |= 0x00000010;
      }
      /**
       * <pre>
       * IDs of MenuItem entities that correspond to this MenuSection entity. A
       * section is expected to have at least 1 item if it does not contain any
       * sub-sections.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @return A list containing the menuItemIds.
       */
      public com.google.protobuf.ProtocolStringList
          getMenuItemIdsList() {
        menuItemIds_.makeImmutable();
        return menuItemIds_;
      }
      /**
       * <pre>
       * IDs of MenuItem entities that correspond to this MenuSection entity. A
       * section is expected to have at least 1 item if it does not contain any
       * sub-sections.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @return The count of menuItemIds.
       */
      public int getMenuItemIdsCount() {
        return menuItemIds_.size();
      }
      /**
       * <pre>
       * IDs of MenuItem entities that correspond to this MenuSection entity. A
       * section is expected to have at least 1 item if it does not contain any
       * sub-sections.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @param index The index of the element to return.
       * @return The menuItemIds at the given index.
       */
      public java.lang.String getMenuItemIds(int index) {
        return menuItemIds_.get(index);
      }
      /**
       * <pre>
       * IDs of MenuItem entities that correspond to this MenuSection entity. A
       * section is expected to have at least 1 item if it does not contain any
       * sub-sections.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @param index The index of the value to return.
       * @return The bytes of the menuItemIds at the given index.
       */
      public com.google.protobuf.ByteString
          getMenuItemIdsBytes(int index) {
        return menuItemIds_.getByteString(index);
      }
      /**
       * <pre>
       * IDs of MenuItem entities that correspond to this MenuSection entity. A
       * section is expected to have at least 1 item if it does not contain any
       * sub-sections.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @param index The index to set the value at.
       * @param value The menuItemIds to set.
       * @return This builder for chaining.
       */
      public Builder setMenuItemIds(
          int index, java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        ensureMenuItemIdsIsMutable();
        menuItemIds_.set(index, value);
        bitField0_ |= 0x00000010;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * IDs of MenuItem entities that correspond to this MenuSection entity. A
       * section is expected to have at least 1 item if it does not contain any
       * sub-sections.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @param value The menuItemIds to add.
       * @return This builder for chaining.
       */
      public Builder addMenuItemIds(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        ensureMenuItemIdsIsMutable();
        menuItemIds_.add(value);
        bitField0_ |= 0x00000010;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * IDs of MenuItem entities that correspond to this MenuSection entity. A
       * section is expected to have at least 1 item if it does not contain any
       * sub-sections.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @param values The menuItemIds to add.
       * @return This builder for chaining.
       */
      public Builder addAllMenuItemIds(
          java.lang.Iterable<java.lang.String> values) {
        ensureMenuItemIdsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, menuItemIds_);
        bitField0_ |= 0x00000010;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * IDs of MenuItem entities that correspond to this MenuSection entity. A
       * section is expected to have at least 1 item if it does not contain any
       * sub-sections.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearMenuItemIds() {
        menuItemIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
        bitField0_ = (bitField0_ & ~0x00000010);;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * IDs of MenuItem entities that correspond to this MenuSection entity. A
       * section is expected to have at least 1 item if it does not contain any
       * sub-sections.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_item_ids = 6;</code>
       * @param value The bytes of the menuItemIds to add.
       * @return This builder for chaining.
       */
      public Builder addMenuItemIdsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        ensureMenuItemIdsIsMutable();
        menuItemIds_.add(value);
        bitField0_ |= 0x00000010;
        onChanged();
        return this;
      }

      private com.google.protobuf.LazyStringArrayList menuSectionIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
      private void ensureMenuSectionIdsIsMutable() {
        if (!menuSectionIds_.isModifiable()) {
          menuSectionIds_ = new com.google.protobuf.LazyStringArrayList(menuSectionIds_);
        }
        bitField0_ |= 0x00000020;
      }
      /**
       * <pre>
       * Child MenuSections (sub-sections) that correspond to this MenuSection
       * entity.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @return A list containing the menuSectionIds.
       */
      public com.google.protobuf.ProtocolStringList
          getMenuSectionIdsList() {
        menuSectionIds_.makeImmutable();
        return menuSectionIds_;
      }
      /**
       * <pre>
       * Child MenuSections (sub-sections) that correspond to this MenuSection
       * entity.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @return The count of menuSectionIds.
       */
      public int getMenuSectionIdsCount() {
        return menuSectionIds_.size();
      }
      /**
       * <pre>
       * Child MenuSections (sub-sections) that correspond to this MenuSection
       * entity.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @param index The index of the element to return.
       * @return The menuSectionIds at the given index.
       */
      public java.lang.String getMenuSectionIds(int index) {
        return menuSectionIds_.get(index);
      }
      /**
       * <pre>
       * Child MenuSections (sub-sections) that correspond to this MenuSection
       * entity.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @param index The index of the value to return.
       * @return The bytes of the menuSectionIds at the given index.
       */
      public com.google.protobuf.ByteString
          getMenuSectionIdsBytes(int index) {
        return menuSectionIds_.getByteString(index);
      }
      /**
       * <pre>
       * Child MenuSections (sub-sections) that correspond to this MenuSection
       * entity.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @param index The index to set the value at.
       * @param value The menuSectionIds to set.
       * @return This builder for chaining.
       */
      public Builder setMenuSectionIds(
          int index, java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        ensureMenuSectionIdsIsMutable();
        menuSectionIds_.set(index, value);
        bitField0_ |= 0x00000020;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Child MenuSections (sub-sections) that correspond to this MenuSection
       * entity.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @param value The menuSectionIds to add.
       * @return This builder for chaining.
       */
      public Builder addMenuSectionIds(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        ensureMenuSectionIdsIsMutable();
        menuSectionIds_.add(value);
        bitField0_ |= 0x00000020;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Child MenuSections (sub-sections) that correspond to this MenuSection
       * entity.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @param values The menuSectionIds to add.
       * @return This builder for chaining.
       */
      public Builder addAllMenuSectionIds(
          java.lang.Iterable<java.lang.String> values) {
        ensureMenuSectionIdsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, menuSectionIds_);
        bitField0_ |= 0x00000020;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Child MenuSections (sub-sections) that correspond to this MenuSection
       * entity.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearMenuSectionIds() {
        menuSectionIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
        bitField0_ = (bitField0_ & ~0x00000020);;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Child MenuSections (sub-sections) that correspond to this MenuSection
       * entity.
       * Optional.
       * </pre>
       *
       * <code>repeated string menu_section_ids = 7;</code>
       * @param value The bytes of the menuSectionIds to add.
       * @return This builder for chaining.
       */
      public Builder addMenuSectionIdsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        ensureMenuSectionIdsIsMutable();
        menuSectionIds_.add(value);
        bitField0_ |= 0x00000020;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.MenuSection)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.MenuSection)
    private static final food.menu.v1.FoodMenu.MenuSection DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.MenuSection();
    }

    public static food.menu.v1.FoodMenu.MenuSection getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<MenuSection>
        PARSER = new com.google.protobuf.AbstractParser<MenuSection>() {
      @java.lang.Override
      public MenuSection parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<MenuSection> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<MenuSection> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuSection getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface MenuItemOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.MenuItem)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * An opaque string from an partner which uniquely identifies the MenuItem
     * within the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_item_id = 1;</code>
     * @return The menuItemId.
     */
    java.lang.String getMenuItemId();
    /**
     * <pre>
     * An opaque string from an partner which uniquely identifies the MenuItem
     * within the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_item_id = 1;</code>
     * @return The bytes for menuItemId.
     */
    com.google.protobuf.ByteString
        getMenuItemIdBytes();

    /**
     * <pre>
     * The name that can identify the MenuItem when a user is browsing the menu.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 2;</code>
     * @return Whether the displayName field is set.
     */
    boolean hasDisplayName();
    /**
     * <pre>
     * The name that can identify the MenuItem when a user is browsing the menu.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 2;</code>
     * @return The displayName.
     */
    food.menu.v1.FoodMenu.TextField getDisplayName();
    /**
     * <pre>
     * The name that can identify the MenuItem when a user is browsing the menu.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 2;</code>
     */
    food.menu.v1.FoodMenu.TextFieldOrBuilder getDisplayNameOrBuilder();

    /**
     * <pre>
     * A description of the menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 3;</code>
     * @return Whether the description field is set.
     */
    boolean hasDescription();
    /**
     * <pre>
     * A description of the menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 3;</code>
     * @return The description.
     */
    food.menu.v1.FoodMenu.TextField getDescription();
    /**
     * <pre>
     * A description of the menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 3;</code>
     */
    food.menu.v1.FoodMenu.TextFieldOrBuilder getDescriptionOrBuilder();

    /**
     * <pre>
     * Image(s) of the menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    java.util.List<food.menu.v1.FoodMenu.Image> 
        getImagesList();
    /**
     * <pre>
     * Image(s) of the menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    food.menu.v1.FoodMenu.Image getImages(int index);
    /**
     * <pre>
     * Image(s) of the menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    int getImagesCount();
    /**
     * <pre>
     * Image(s) of the menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    java.util.List<? extends food.menu.v1.FoodMenu.ImageOrBuilder> 
        getImagesOrBuilderList();
    /**
     * <pre>
     * Image(s) of the menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    food.menu.v1.FoodMenu.ImageOrBuilder getImagesOrBuilder(
        int index);

    /**
     * <pre>
     * Available offers to purchase this food item.
     * </pre>
     *
     * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
     * @return Whether the offerSet field is set.
     */
    boolean hasOfferSet();
    /**
     * <pre>
     * Available offers to purchase this food item.
     * </pre>
     *
     * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
     * @return The offerSet.
     */
    food.menu.v1.FoodMenu.OfferSet getOfferSet();
    /**
     * <pre>
     * Available offers to purchase this food item.
     * </pre>
     *
     * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
     */
    food.menu.v1.FoodMenu.OfferSetOrBuilder getOfferSetOrBuilder();

    /**
     * <pre>
     * Available options for this menu item.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
     * @return Whether the menuItemOptionSet field is set.
     */
    boolean hasMenuItemOptionSet();
    /**
     * <pre>
     * Available options for this menu item.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
     * @return The menuItemOptionSet.
     */
    food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet getMenuItemOptionSet();
    /**
     * <pre>
     * Available options for this menu item.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
     */
    food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSetOrBuilder getMenuItemOptionSetOrBuilder();

    /**
     * <pre>
     * Attributes about this menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
     * @return Whether the itemAttributes field is set.
     */
    boolean hasItemAttributes();
    /**
     * <pre>
     * Attributes about this menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
     * @return The itemAttributes.
     */
    food.menu.v1.FoodMenu.MenuItemAttributes getItemAttributes();
    /**
     * <pre>
     * Attributes about this menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
     */
    food.menu.v1.FoodMenu.MenuItemAttributesOrBuilder getItemAttributesOrBuilder();

    food.menu.v1.FoodMenu.MenuItem.PricingCase getPricingCase();
  }
  /**
   * <pre>
   * Represents a single food or drink item offered by a Food establishment.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.MenuItem}
   */
  public static final class MenuItem extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.MenuItem)
      MenuItemOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use MenuItem.newBuilder() to construct.
    private MenuItem(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private MenuItem() {
      menuItemId_ = "";
      images_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new MenuItem();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItem_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItem_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.MenuItem.class, food.menu.v1.FoodMenu.MenuItem.Builder.class);
    }

    public interface MenuItemOptionSetOrBuilder extends
        // @@protoc_insertion_point(interface_extends:food.menu.v1.MenuItem.MenuItemOptionSet)
        com.google.protobuf.MessageOrBuilder {

      /**
       * <pre>
       * IDs of menu item options that are applicable to this menu item.
       * Required.
       * </pre>
       *
       * <code>repeated string menu_item_option_ids = 1;</code>
       * @return A list containing the menuItemOptionIds.
       */
      java.util.List<java.lang.String>
          getMenuItemOptionIdsList();
      /**
       * <pre>
       * IDs of menu item options that are applicable to this menu item.
       * Required.
       * </pre>
       *
       * <code>repeated string menu_item_option_ids = 1;</code>
       * @return The count of menuItemOptionIds.
       */
      int getMenuItemOptionIdsCount();
      /**
       * <pre>
       * IDs of menu item options that are applicable to this menu item.
       * Required.
       * </pre>
       *
       * <code>repeated string menu_item_option_ids = 1;</code>
       * @param index The index of the element to return.
       * @return The menuItemOptionIds at the given index.
       */
      java.lang.String getMenuItemOptionIds(int index);
      /**
       * <pre>
       * IDs of menu item options that are applicable to this menu item.
       * Required.
       * </pre>
       *
       * <code>repeated string menu_item_option_ids = 1;</code>
       * @param index The index of the value to return.
       * @return The bytes of the menuItemOptionIds at the given index.
       */
      com.google.protobuf.ByteString
          getMenuItemOptionIdsBytes(int index);
    }
    /**
     * <pre>
     * Container that specifies a list of options available on an item.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.MenuItem.MenuItemOptionSet}
     */
    public static final class MenuItemOptionSet extends
        com.google.protobuf.GeneratedMessageV3 implements
        // @@protoc_insertion_point(message_implements:food.menu.v1.MenuItem.MenuItemOptionSet)
        MenuItemOptionSetOrBuilder {
    private static final long serialVersionUID = 0L;
      // Use MenuItemOptionSet.newBuilder() to construct.
      private MenuItemOptionSet(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
        super(builder);
      }
      private MenuItemOptionSet() {
        menuItemOptionIds_ =
            com.google.protobuf.LazyStringArrayList.emptyList();
      }

      @java.lang.Override
      @SuppressWarnings({"unused"})
      protected java.lang.Object newInstance(
          UnusedPrivateParameter unused) {
        return new MenuItemOptionSet();
      }

      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItem_MenuItemOptionSet_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItem_MenuItemOptionSet_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.class, food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.Builder.class);
      }

      public static final int MENU_ITEM_OPTION_IDS_FIELD_NUMBER = 1;
      @SuppressWarnings("serial")
      private com.google.protobuf.LazyStringArrayList menuItemOptionIds_ =
          com.google.protobuf.LazyStringArrayList.emptyList();
      /**
       * <pre>
       * IDs of menu item options that are applicable to this menu item.
       * Required.
       * </pre>
       *
       * <code>repeated string menu_item_option_ids = 1;</code>
       * @return A list containing the menuItemOptionIds.
       */
      public com.google.protobuf.ProtocolStringList
          getMenuItemOptionIdsList() {
        return menuItemOptionIds_;
      }
      /**
       * <pre>
       * IDs of menu item options that are applicable to this menu item.
       * Required.
       * </pre>
       *
       * <code>repeated string menu_item_option_ids = 1;</code>
       * @return The count of menuItemOptionIds.
       */
      public int getMenuItemOptionIdsCount() {
        return menuItemOptionIds_.size();
      }
      /**
       * <pre>
       * IDs of menu item options that are applicable to this menu item.
       * Required.
       * </pre>
       *
       * <code>repeated string menu_item_option_ids = 1;</code>
       * @param index The index of the element to return.
       * @return The menuItemOptionIds at the given index.
       */
      public java.lang.String getMenuItemOptionIds(int index) {
        return menuItemOptionIds_.get(index);
      }
      /**
       * <pre>
       * IDs of menu item options that are applicable to this menu item.
       * Required.
       * </pre>
       *
       * <code>repeated string menu_item_option_ids = 1;</code>
       * @param index The index of the value to return.
       * @return The bytes of the menuItemOptionIds at the given index.
       */
      public com.google.protobuf.ByteString
          getMenuItemOptionIdsBytes(int index) {
        return menuItemOptionIds_.getByteString(index);
      }

      private byte memoizedIsInitialized = -1;
      @java.lang.Override
      public final boolean isInitialized() {
        byte isInitialized = memoizedIsInitialized;
        if (isInitialized == 1) return true;
        if (isInitialized == 0) return false;

        memoizedIsInitialized = 1;
        return true;
      }

      @java.lang.Override
      public void writeTo(com.google.protobuf.CodedOutputStream output)
                          throws java.io.IOException {
        for (int i = 0; i < menuItemOptionIds_.size(); i++) {
          com.google.protobuf.GeneratedMessageV3.writeString(output, 1, menuItemOptionIds_.getRaw(i));
        }
        getUnknownFields().writeTo(output);
      }

      @java.lang.Override
      public int getSerializedSize() {
        int size = memoizedSize;
        if (size != -1) return size;

        size = 0;
        {
          int dataSize = 0;
          for (int i = 0; i < menuItemOptionIds_.size(); i++) {
            dataSize += computeStringSizeNoTag(menuItemOptionIds_.getRaw(i));
          }
          size += dataSize;
          size += 1 * getMenuItemOptionIdsList().size();
        }
        size += getUnknownFields().getSerializedSize();
        memoizedSize = size;
        return size;
      }

      @java.lang.Override
      public boolean equals(final java.lang.Object obj) {
        if (obj == this) {
         return true;
        }
        if (!(obj instanceof food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet)) {
          return super.equals(obj);
        }
        food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet other = (food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet) obj;

        if (!getMenuItemOptionIdsList()
            .equals(other.getMenuItemOptionIdsList())) return false;
        if (!getUnknownFields().equals(other.getUnknownFields())) return false;
        return true;
      }

      @java.lang.Override
      public int hashCode() {
        if (memoizedHashCode != 0) {
          return memoizedHashCode;
        }
        int hash = 41;
        hash = (19 * hash) + getDescriptor().hashCode();
        if (getMenuItemOptionIdsCount() > 0) {
          hash = (37 * hash) + MENU_ITEM_OPTION_IDS_FIELD_NUMBER;
          hash = (53 * hash) + getMenuItemOptionIdsList().hashCode();
        }
        hash = (29 * hash) + getUnknownFields().hashCode();
        memoizedHashCode = hash;
        return hash;
      }

      public static food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet parseFrom(
          java.nio.ByteBuffer data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data);
      }
      public static food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet parseFrom(
          java.nio.ByteBuffer data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data, extensionRegistry);
      }
      public static food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet parseFrom(
          com.google.protobuf.ByteString data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data);
      }
      public static food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet parseFrom(
          com.google.protobuf.ByteString data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data, extensionRegistry);
      }
      public static food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet parseFrom(byte[] data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data);
      }
      public static food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet parseFrom(
          byte[] data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data, extensionRegistry);
      }
      public static food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet parseFrom(java.io.InputStream input)
          throws java.io.IOException {
        return com.google.protobuf.GeneratedMessageV3
            .parseWithIOException(PARSER, input);
      }
      public static food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet parseFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return com.google.protobuf.GeneratedMessageV3
            .parseWithIOException(PARSER, input, extensionRegistry);
      }
      public static food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet parseDelimitedFrom(java.io.InputStream input)
          throws java.io.IOException {
        return com.google.protobuf.GeneratedMessageV3
            .parseDelimitedWithIOException(PARSER, input);
      }
      public static food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet parseDelimitedFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return com.google.protobuf.GeneratedMessageV3
            .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
      }
      public static food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet parseFrom(
          com.google.protobuf.CodedInputStream input)
          throws java.io.IOException {
        return com.google.protobuf.GeneratedMessageV3
            .parseWithIOException(PARSER, input);
      }
      public static food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet parseFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return com.google.protobuf.GeneratedMessageV3
            .parseWithIOException(PARSER, input, extensionRegistry);
      }

      @java.lang.Override
      public Builder newBuilderForType() { return newBuilder(); }
      public static Builder newBuilder() {
        return DEFAULT_INSTANCE.toBuilder();
      }
      public static Builder newBuilder(food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet prototype) {
        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
      }
      @java.lang.Override
      public Builder toBuilder() {
        return this == DEFAULT_INSTANCE
            ? new Builder() : new Builder().mergeFrom(this);
      }

      @java.lang.Override
      protected Builder newBuilderForType(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        Builder builder = new Builder(parent);
        return builder;
      }
      /**
       * <pre>
       * Container that specifies a list of options available on an item.
       * </pre>
       *
       * Protobuf type {@code food.menu.v1.MenuItem.MenuItemOptionSet}
       */
      public static final class Builder extends
          com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
          // @@protoc_insertion_point(builder_implements:food.menu.v1.MenuItem.MenuItemOptionSet)
          food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSetOrBuilder {
        public static final com.google.protobuf.Descriptors.Descriptor
            getDescriptor() {
          return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItem_MenuItemOptionSet_descriptor;
        }

        @java.lang.Override
        protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
            internalGetFieldAccessorTable() {
          return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItem_MenuItemOptionSet_fieldAccessorTable
              .ensureFieldAccessorsInitialized(
                  food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.class, food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.Builder.class);
        }

        // Construct using food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.newBuilder()
        private Builder() {

        }

        private Builder(
            com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
          super(parent);

        }
        @java.lang.Override
        public Builder clear() {
          super.clear();
          bitField0_ = 0;
          menuItemOptionIds_ =
              com.google.protobuf.LazyStringArrayList.emptyList();
          return this;
        }

        @java.lang.Override
        public com.google.protobuf.Descriptors.Descriptor
            getDescriptorForType() {
          return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItem_MenuItemOptionSet_descriptor;
        }

        @java.lang.Override
        public food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet getDefaultInstanceForType() {
          return food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.getDefaultInstance();
        }

        @java.lang.Override
        public food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet build() {
          food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(result);
          }
          return result;
        }

        @java.lang.Override
        public food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet buildPartial() {
          food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet result = new food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet(this);
          if (bitField0_ != 0) { buildPartial0(result); }
          onBuilt();
          return result;
        }

        private void buildPartial0(food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet result) {
          int from_bitField0_ = bitField0_;
          if (((from_bitField0_ & 0x00000001) != 0)) {
            menuItemOptionIds_.makeImmutable();
            result.menuItemOptionIds_ = menuItemOptionIds_;
          }
        }

        @java.lang.Override
        public Builder mergeFrom(com.google.protobuf.Message other) {
          if (other instanceof food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet) {
            return mergeFrom((food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet)other);
          } else {
            super.mergeFrom(other);
            return this;
          }
        }

        public Builder mergeFrom(food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet other) {
          if (other == food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.getDefaultInstance()) return this;
          if (!other.menuItemOptionIds_.isEmpty()) {
            if (menuItemOptionIds_.isEmpty()) {
              menuItemOptionIds_ = other.menuItemOptionIds_;
              bitField0_ |= 0x00000001;
            } else {
              ensureMenuItemOptionIdsIsMutable();
              menuItemOptionIds_.addAll(other.menuItemOptionIds_);
            }
            onChanged();
          }
          this.mergeUnknownFields(other.getUnknownFields());
          onChanged();
          return this;
        }

        @java.lang.Override
        public final boolean isInitialized() {
          return true;
        }

        @java.lang.Override
        public Builder mergeFrom(
            com.google.protobuf.CodedInputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws java.io.IOException {
          if (extensionRegistry == null) {
            throw new java.lang.NullPointerException();
          }
          try {
            boolean done = false;
            while (!done) {
              int tag = input.readTag();
              switch (tag) {
                case 0:
                  done = true;
                  break;
                case 10: {
                  java.lang.String s = input.readStringRequireUtf8();
                  ensureMenuItemOptionIdsIsMutable();
                  menuItemOptionIds_.add(s);
                  break;
                } // case 10
                default: {
                  if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                    done = true; // was an endgroup tag
                  }
                  break;
                } // default:
              } // switch (tag)
            } // while (!done)
          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
            throw e.unwrapIOException();
          } finally {
            onChanged();
          } // finally
          return this;
        }
        private int bitField0_;

        private com.google.protobuf.LazyStringArrayList menuItemOptionIds_ =
            com.google.protobuf.LazyStringArrayList.emptyList();
        private void ensureMenuItemOptionIdsIsMutable() {
          if (!menuItemOptionIds_.isModifiable()) {
            menuItemOptionIds_ = new com.google.protobuf.LazyStringArrayList(menuItemOptionIds_);
          }
          bitField0_ |= 0x00000001;
        }
        /**
         * <pre>
         * IDs of menu item options that are applicable to this menu item.
         * Required.
         * </pre>
         *
         * <code>repeated string menu_item_option_ids = 1;</code>
         * @return A list containing the menuItemOptionIds.
         */
        public com.google.protobuf.ProtocolStringList
            getMenuItemOptionIdsList() {
          menuItemOptionIds_.makeImmutable();
          return menuItemOptionIds_;
        }
        /**
         * <pre>
         * IDs of menu item options that are applicable to this menu item.
         * Required.
         * </pre>
         *
         * <code>repeated string menu_item_option_ids = 1;</code>
         * @return The count of menuItemOptionIds.
         */
        public int getMenuItemOptionIdsCount() {
          return menuItemOptionIds_.size();
        }
        /**
         * <pre>
         * IDs of menu item options that are applicable to this menu item.
         * Required.
         * </pre>
         *
         * <code>repeated string menu_item_option_ids = 1;</code>
         * @param index The index of the element to return.
         * @return The menuItemOptionIds at the given index.
         */
        public java.lang.String getMenuItemOptionIds(int index) {
          return menuItemOptionIds_.get(index);
        }
        /**
         * <pre>
         * IDs of menu item options that are applicable to this menu item.
         * Required.
         * </pre>
         *
         * <code>repeated string menu_item_option_ids = 1;</code>
         * @param index The index of the value to return.
         * @return The bytes of the menuItemOptionIds at the given index.
         */
        public com.google.protobuf.ByteString
            getMenuItemOptionIdsBytes(int index) {
          return menuItemOptionIds_.getByteString(index);
        }
        /**
         * <pre>
         * IDs of menu item options that are applicable to this menu item.
         * Required.
         * </pre>
         *
         * <code>repeated string menu_item_option_ids = 1;</code>
         * @param index The index to set the value at.
         * @param value The menuItemOptionIds to set.
         * @return This builder for chaining.
         */
        public Builder setMenuItemOptionIds(
            int index, java.lang.String value) {
          if (value == null) { throw new NullPointerException(); }
          ensureMenuItemOptionIdsIsMutable();
          menuItemOptionIds_.set(index, value);
          bitField0_ |= 0x00000001;
          onChanged();
          return this;
        }
        /**
         * <pre>
         * IDs of menu item options that are applicable to this menu item.
         * Required.
         * </pre>
         *
         * <code>repeated string menu_item_option_ids = 1;</code>
         * @param value The menuItemOptionIds to add.
         * @return This builder for chaining.
         */
        public Builder addMenuItemOptionIds(
            java.lang.String value) {
          if (value == null) { throw new NullPointerException(); }
          ensureMenuItemOptionIdsIsMutable();
          menuItemOptionIds_.add(value);
          bitField0_ |= 0x00000001;
          onChanged();
          return this;
        }
        /**
         * <pre>
         * IDs of menu item options that are applicable to this menu item.
         * Required.
         * </pre>
         *
         * <code>repeated string menu_item_option_ids = 1;</code>
         * @param values The menuItemOptionIds to add.
         * @return This builder for chaining.
         */
        public Builder addAllMenuItemOptionIds(
            java.lang.Iterable<java.lang.String> values) {
          ensureMenuItemOptionIdsIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, menuItemOptionIds_);
          bitField0_ |= 0x00000001;
          onChanged();
          return this;
        }
        /**
         * <pre>
         * IDs of menu item options that are applicable to this menu item.
         * Required.
         * </pre>
         *
         * <code>repeated string menu_item_option_ids = 1;</code>
         * @return This builder for chaining.
         */
        public Builder clearMenuItemOptionIds() {
          menuItemOptionIds_ =
            com.google.protobuf.LazyStringArrayList.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);;
          onChanged();
          return this;
        }
        /**
         * <pre>
         * IDs of menu item options that are applicable to this menu item.
         * Required.
         * </pre>
         *
         * <code>repeated string menu_item_option_ids = 1;</code>
         * @param value The bytes of the menuItemOptionIds to add.
         * @return This builder for chaining.
         */
        public Builder addMenuItemOptionIdsBytes(
            com.google.protobuf.ByteString value) {
          if (value == null) { throw new NullPointerException(); }
          checkByteStringIsUtf8(value);
          ensureMenuItemOptionIdsIsMutable();
          menuItemOptionIds_.add(value);
          bitField0_ |= 0x00000001;
          onChanged();
          return this;
        }
        @java.lang.Override
        public final Builder setUnknownFields(
            final com.google.protobuf.UnknownFieldSet unknownFields) {
          return super.setUnknownFields(unknownFields);
        }

        @java.lang.Override
        public final Builder mergeUnknownFields(
            final com.google.protobuf.UnknownFieldSet unknownFields) {
          return super.mergeUnknownFields(unknownFields);
        }


        // @@protoc_insertion_point(builder_scope:food.menu.v1.MenuItem.MenuItemOptionSet)
      }

      // @@protoc_insertion_point(class_scope:food.menu.v1.MenuItem.MenuItemOptionSet)
      private static final food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet DEFAULT_INSTANCE;
      static {
        DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet();
      }

      public static food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet getDefaultInstance() {
        return DEFAULT_INSTANCE;
      }

      private static final com.google.protobuf.Parser<MenuItemOptionSet>
          PARSER = new com.google.protobuf.AbstractParser<MenuItemOptionSet>() {
        @java.lang.Override
        public MenuItemOptionSet parsePartialFrom(
            com.google.protobuf.CodedInputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws com.google.protobuf.InvalidProtocolBufferException {
          Builder builder = newBuilder();
          try {
            builder.mergeFrom(input, extensionRegistry);
          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
            throw e.setUnfinishedMessage(builder.buildPartial());
          } catch (com.google.protobuf.UninitializedMessageException e) {
            throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
          } catch (java.io.IOException e) {
            throw new com.google.protobuf.InvalidProtocolBufferException(e)
                .setUnfinishedMessage(builder.buildPartial());
          }
          return builder.buildPartial();
        }
      };

      public static com.google.protobuf.Parser<MenuItemOptionSet> parser() {
        return PARSER;
      }

      @java.lang.Override
      public com.google.protobuf.Parser<MenuItemOptionSet> getParserForType() {
        return PARSER;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet getDefaultInstanceForType() {
        return DEFAULT_INSTANCE;
      }

    }

    private int pricingCase_ = 0;
    @SuppressWarnings("serial")
    private java.lang.Object pricing_;
    public enum PricingCase
        implements com.google.protobuf.Internal.EnumLite,
            com.google.protobuf.AbstractMessage.InternalOneOfEnum {
      OFFER_SET(6),
      MENU_ITEM_OPTION_SET(7),
      PRICING_NOT_SET(0);
      private final int value;
      private PricingCase(int value) {
        this.value = value;
      }
      /**
       * @param value The number of the enum to look for.
       * @return The enum associated with the given number.
       * @deprecated Use {@link #forNumber(int)} instead.
       */
      @java.lang.Deprecated
      public static PricingCase valueOf(int value) {
        return forNumber(value);
      }

      public static PricingCase forNumber(int value) {
        switch (value) {
          case 6: return OFFER_SET;
          case 7: return MENU_ITEM_OPTION_SET;
          case 0: return PRICING_NOT_SET;
          default: return null;
        }
      }
      public int getNumber() {
        return this.value;
      }
    };

    public PricingCase
    getPricingCase() {
      return PricingCase.forNumber(
          pricingCase_);
    }

    public static final int MENU_ITEM_ID_FIELD_NUMBER = 1;
    @SuppressWarnings("serial")
    private volatile java.lang.Object menuItemId_ = "";
    /**
     * <pre>
     * An opaque string from an partner which uniquely identifies the MenuItem
     * within the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_item_id = 1;</code>
     * @return The menuItemId.
     */
    @java.lang.Override
    public java.lang.String getMenuItemId() {
      java.lang.Object ref = menuItemId_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        menuItemId_ = s;
        return s;
      }
    }
    /**
     * <pre>
     * An opaque string from an partner which uniquely identifies the MenuItem
     * within the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_item_id = 1;</code>
     * @return The bytes for menuItemId.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getMenuItemIdBytes() {
      java.lang.Object ref = menuItemId_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        menuItemId_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int DISPLAY_NAME_FIELD_NUMBER = 2;
    private food.menu.v1.FoodMenu.TextField displayName_;
    /**
     * <pre>
     * The name that can identify the MenuItem when a user is browsing the menu.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 2;</code>
     * @return Whether the displayName field is set.
     */
    @java.lang.Override
    public boolean hasDisplayName() {
      return displayName_ != null;
    }
    /**
     * <pre>
     * The name that can identify the MenuItem when a user is browsing the menu.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 2;</code>
     * @return The displayName.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextField getDisplayName() {
      return displayName_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : displayName_;
    }
    /**
     * <pre>
     * The name that can identify the MenuItem when a user is browsing the menu.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField display_name = 2;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextFieldOrBuilder getDisplayNameOrBuilder() {
      return displayName_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : displayName_;
    }

    public static final int DESCRIPTION_FIELD_NUMBER = 3;
    private food.menu.v1.FoodMenu.TextField description_;
    /**
     * <pre>
     * A description of the menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 3;</code>
     * @return Whether the description field is set.
     */
    @java.lang.Override
    public boolean hasDescription() {
      return description_ != null;
    }
    /**
     * <pre>
     * A description of the menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 3;</code>
     * @return The description.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextField getDescription() {
      return description_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : description_;
    }
    /**
     * <pre>
     * A description of the menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 3;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextFieldOrBuilder getDescriptionOrBuilder() {
      return description_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : description_;
    }

    public static final int IMAGES_FIELD_NUMBER = 4;
    @SuppressWarnings("serial")
    private java.util.List<food.menu.v1.FoodMenu.Image> images_;
    /**
     * <pre>
     * Image(s) of the menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    @java.lang.Override
    public java.util.List<food.menu.v1.FoodMenu.Image> getImagesList() {
      return images_;
    }
    /**
     * <pre>
     * Image(s) of the menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    @java.lang.Override
    public java.util.List<? extends food.menu.v1.FoodMenu.ImageOrBuilder> 
        getImagesOrBuilderList() {
      return images_;
    }
    /**
     * <pre>
     * Image(s) of the menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    @java.lang.Override
    public int getImagesCount() {
      return images_.size();
    }
    /**
     * <pre>
     * Image(s) of the menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.Image getImages(int index) {
      return images_.get(index);
    }
    /**
     * <pre>
     * Image(s) of the menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Image images = 4;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.ImageOrBuilder getImagesOrBuilder(
        int index) {
      return images_.get(index);
    }

    public static final int OFFER_SET_FIELD_NUMBER = 6;
    /**
     * <pre>
     * Available offers to purchase this food item.
     * </pre>
     *
     * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
     * @return Whether the offerSet field is set.
     */
    @java.lang.Override
    public boolean hasOfferSet() {
      return pricingCase_ == 6;
    }
    /**
     * <pre>
     * Available offers to purchase this food item.
     * </pre>
     *
     * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
     * @return The offerSet.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.OfferSet getOfferSet() {
      if (pricingCase_ == 6) {
         return (food.menu.v1.FoodMenu.OfferSet) pricing_;
      }
      return food.menu.v1.FoodMenu.OfferSet.getDefaultInstance();
    }
    /**
     * <pre>
     * Available offers to purchase this food item.
     * </pre>
     *
     * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.OfferSetOrBuilder getOfferSetOrBuilder() {
      if (pricingCase_ == 6) {
         return (food.menu.v1.FoodMenu.OfferSet) pricing_;
      }
      return food.menu.v1.FoodMenu.OfferSet.getDefaultInstance();
    }

    public static final int MENU_ITEM_OPTION_SET_FIELD_NUMBER = 7;
    /**
     * <pre>
     * Available options for this menu item.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
     * @return Whether the menuItemOptionSet field is set.
     */
    @java.lang.Override
    public boolean hasMenuItemOptionSet() {
      return pricingCase_ == 7;
    }
    /**
     * <pre>
     * Available options for this menu item.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
     * @return The menuItemOptionSet.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet getMenuItemOptionSet() {
      if (pricingCase_ == 7) {
         return (food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet) pricing_;
      }
      return food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.getDefaultInstance();
    }
    /**
     * <pre>
     * Available options for this menu item.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSetOrBuilder getMenuItemOptionSetOrBuilder() {
      if (pricingCase_ == 7) {
         return (food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet) pricing_;
      }
      return food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.getDefaultInstance();
    }

    public static final int ITEM_ATTRIBUTES_FIELD_NUMBER = 8;
    private food.menu.v1.FoodMenu.MenuItemAttributes itemAttributes_;
    /**
     * <pre>
     * Attributes about this menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
     * @return Whether the itemAttributes field is set.
     */
    @java.lang.Override
    public boolean hasItemAttributes() {
      return itemAttributes_ != null;
    }
    /**
     * <pre>
     * Attributes about this menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
     * @return The itemAttributes.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItemAttributes getItemAttributes() {
      return itemAttributes_ == null ? food.menu.v1.FoodMenu.MenuItemAttributes.getDefaultInstance() : itemAttributes_;
    }
    /**
     * <pre>
     * Attributes about this menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItemAttributesOrBuilder getItemAttributesOrBuilder() {
      return itemAttributes_ == null ? food.menu.v1.FoodMenu.MenuItemAttributes.getDefaultInstance() : itemAttributes_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(menuItemId_)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, menuItemId_);
      }
      if (displayName_ != null) {
        output.writeMessage(2, getDisplayName());
      }
      if (description_ != null) {
        output.writeMessage(3, getDescription());
      }
      for (int i = 0; i < images_.size(); i++) {
        output.writeMessage(4, images_.get(i));
      }
      if (pricingCase_ == 6) {
        output.writeMessage(6, (food.menu.v1.FoodMenu.OfferSet) pricing_);
      }
      if (pricingCase_ == 7) {
        output.writeMessage(7, (food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet) pricing_);
      }
      if (itemAttributes_ != null) {
        output.writeMessage(8, getItemAttributes());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(menuItemId_)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, menuItemId_);
      }
      if (displayName_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getDisplayName());
      }
      if (description_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getDescription());
      }
      for (int i = 0; i < images_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, images_.get(i));
      }
      if (pricingCase_ == 6) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(6, (food.menu.v1.FoodMenu.OfferSet) pricing_);
      }
      if (pricingCase_ == 7) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(7, (food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet) pricing_);
      }
      if (itemAttributes_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(8, getItemAttributes());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.MenuItem)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.MenuItem other = (food.menu.v1.FoodMenu.MenuItem) obj;

      if (!getMenuItemId()
          .equals(other.getMenuItemId())) return false;
      if (hasDisplayName() != other.hasDisplayName()) return false;
      if (hasDisplayName()) {
        if (!getDisplayName()
            .equals(other.getDisplayName())) return false;
      }
      if (hasDescription() != other.hasDescription()) return false;
      if (hasDescription()) {
        if (!getDescription()
            .equals(other.getDescription())) return false;
      }
      if (!getImagesList()
          .equals(other.getImagesList())) return false;
      if (hasItemAttributes() != other.hasItemAttributes()) return false;
      if (hasItemAttributes()) {
        if (!getItemAttributes()
            .equals(other.getItemAttributes())) return false;
      }
      if (!getPricingCase().equals(other.getPricingCase())) return false;
      switch (pricingCase_) {
        case 6:
          if (!getOfferSet()
              .equals(other.getOfferSet())) return false;
          break;
        case 7:
          if (!getMenuItemOptionSet()
              .equals(other.getMenuItemOptionSet())) return false;
          break;
        case 0:
        default:
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      hash = (37 * hash) + MENU_ITEM_ID_FIELD_NUMBER;
      hash = (53 * hash) + getMenuItemId().hashCode();
      if (hasDisplayName()) {
        hash = (37 * hash) + DISPLAY_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getDisplayName().hashCode();
      }
      if (hasDescription()) {
        hash = (37 * hash) + DESCRIPTION_FIELD_NUMBER;
        hash = (53 * hash) + getDescription().hashCode();
      }
      if (getImagesCount() > 0) {
        hash = (37 * hash) + IMAGES_FIELD_NUMBER;
        hash = (53 * hash) + getImagesList().hashCode();
      }
      if (hasItemAttributes()) {
        hash = (37 * hash) + ITEM_ATTRIBUTES_FIELD_NUMBER;
        hash = (53 * hash) + getItemAttributes().hashCode();
      }
      switch (pricingCase_) {
        case 6:
          hash = (37 * hash) + OFFER_SET_FIELD_NUMBER;
          hash = (53 * hash) + getOfferSet().hashCode();
          break;
        case 7:
          hash = (37 * hash) + MENU_ITEM_OPTION_SET_FIELD_NUMBER;
          hash = (53 * hash) + getMenuItemOptionSet().hashCode();
          break;
        case 0:
        default:
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.MenuItem parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuItem parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItem parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuItem parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItem parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuItem parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItem parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuItem parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItem parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuItem parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItem parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuItem parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.MenuItem prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Represents a single food or drink item offered by a Food establishment.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.MenuItem}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.MenuItem)
        food.menu.v1.FoodMenu.MenuItemOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItem_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItem_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.MenuItem.class, food.menu.v1.FoodMenu.MenuItem.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.MenuItem.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        menuItemId_ = "";
        displayName_ = null;
        if (displayNameBuilder_ != null) {
          displayNameBuilder_.dispose();
          displayNameBuilder_ = null;
        }
        description_ = null;
        if (descriptionBuilder_ != null) {
          descriptionBuilder_.dispose();
          descriptionBuilder_ = null;
        }
        if (imagesBuilder_ == null) {
          images_ = java.util.Collections.emptyList();
        } else {
          images_ = null;
          imagesBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        if (offerSetBuilder_ != null) {
          offerSetBuilder_.clear();
        }
        if (menuItemOptionSetBuilder_ != null) {
          menuItemOptionSetBuilder_.clear();
        }
        itemAttributes_ = null;
        if (itemAttributesBuilder_ != null) {
          itemAttributesBuilder_.dispose();
          itemAttributesBuilder_ = null;
        }
        pricingCase_ = 0;
        pricing_ = null;
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItem_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItem getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.MenuItem.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItem build() {
        food.menu.v1.FoodMenu.MenuItem result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItem buildPartial() {
        food.menu.v1.FoodMenu.MenuItem result = new food.menu.v1.FoodMenu.MenuItem(this);
        buildPartialRepeatedFields(result);
        if (bitField0_ != 0) { buildPartial0(result); }
        buildPartialOneofs(result);
        onBuilt();
        return result;
      }

      private void buildPartialRepeatedFields(food.menu.v1.FoodMenu.MenuItem result) {
        if (imagesBuilder_ == null) {
          if (((bitField0_ & 0x00000008) != 0)) {
            images_ = java.util.Collections.unmodifiableList(images_);
            bitField0_ = (bitField0_ & ~0x00000008);
          }
          result.images_ = images_;
        } else {
          result.images_ = imagesBuilder_.build();
        }
      }

      private void buildPartial0(food.menu.v1.FoodMenu.MenuItem result) {
        int from_bitField0_ = bitField0_;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.menuItemId_ = menuItemId_;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.displayName_ = displayNameBuilder_ == null
              ? displayName_
              : displayNameBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.description_ = descriptionBuilder_ == null
              ? description_
              : descriptionBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000040) != 0)) {
          result.itemAttributes_ = itemAttributesBuilder_ == null
              ? itemAttributes_
              : itemAttributesBuilder_.build();
        }
      }

      private void buildPartialOneofs(food.menu.v1.FoodMenu.MenuItem result) {
        result.pricingCase_ = pricingCase_;
        result.pricing_ = this.pricing_;
        if (pricingCase_ == 6 &&
            offerSetBuilder_ != null) {
          result.pricing_ = offerSetBuilder_.build();
        }
        if (pricingCase_ == 7 &&
            menuItemOptionSetBuilder_ != null) {
          result.pricing_ = menuItemOptionSetBuilder_.build();
        }
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.MenuItem) {
          return mergeFrom((food.menu.v1.FoodMenu.MenuItem)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.MenuItem other) {
        if (other == food.menu.v1.FoodMenu.MenuItem.getDefaultInstance()) return this;
        if (!other.getMenuItemId().isEmpty()) {
          menuItemId_ = other.menuItemId_;
          bitField0_ |= 0x00000001;
          onChanged();
        }
        if (other.hasDisplayName()) {
          mergeDisplayName(other.getDisplayName());
        }
        if (other.hasDescription()) {
          mergeDescription(other.getDescription());
        }
        if (imagesBuilder_ == null) {
          if (!other.images_.isEmpty()) {
            if (images_.isEmpty()) {
              images_ = other.images_;
              bitField0_ = (bitField0_ & ~0x00000008);
            } else {
              ensureImagesIsMutable();
              images_.addAll(other.images_);
            }
            onChanged();
          }
        } else {
          if (!other.images_.isEmpty()) {
            if (imagesBuilder_.isEmpty()) {
              imagesBuilder_.dispose();
              imagesBuilder_ = null;
              images_ = other.images_;
              bitField0_ = (bitField0_ & ~0x00000008);
              imagesBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getImagesFieldBuilder() : null;
            } else {
              imagesBuilder_.addAllMessages(other.images_);
            }
          }
        }
        if (other.hasItemAttributes()) {
          mergeItemAttributes(other.getItemAttributes());
        }
        switch (other.getPricingCase()) {
          case OFFER_SET: {
            mergeOfferSet(other.getOfferSet());
            break;
          }
          case MENU_ITEM_OPTION_SET: {
            mergeMenuItemOptionSet(other.getMenuItemOptionSet());
            break;
          }
          case PRICING_NOT_SET: {
            break;
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                menuItemId_ = input.readStringRequireUtf8();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                input.readMessage(
                    getDisplayNameFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                input.readMessage(
                    getDescriptionFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              case 34: {
                food.menu.v1.FoodMenu.Image m =
                    input.readMessage(
                        food.menu.v1.FoodMenu.Image.parser(),
                        extensionRegistry);
                if (imagesBuilder_ == null) {
                  ensureImagesIsMutable();
                  images_.add(m);
                } else {
                  imagesBuilder_.addMessage(m);
                }
                break;
              } // case 34
              case 50: {
                input.readMessage(
                    getOfferSetFieldBuilder().getBuilder(),
                    extensionRegistry);
                pricingCase_ = 6;
                break;
              } // case 50
              case 58: {
                input.readMessage(
                    getMenuItemOptionSetFieldBuilder().getBuilder(),
                    extensionRegistry);
                pricingCase_ = 7;
                break;
              } // case 58
              case 66: {
                input.readMessage(
                    getItemAttributesFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000040;
                break;
              } // case 66
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int pricingCase_ = 0;
      private java.lang.Object pricing_;
      public PricingCase
          getPricingCase() {
        return PricingCase.forNumber(
            pricingCase_);
      }

      public Builder clearPricing() {
        pricingCase_ = 0;
        pricing_ = null;
        onChanged();
        return this;
      }

      private int bitField0_;

      private java.lang.Object menuItemId_ = "";
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the MenuItem
       * within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_item_id = 1;</code>
       * @return The menuItemId.
       */
      public java.lang.String getMenuItemId() {
        java.lang.Object ref = menuItemId_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          menuItemId_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the MenuItem
       * within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_item_id = 1;</code>
       * @return The bytes for menuItemId.
       */
      public com.google.protobuf.ByteString
          getMenuItemIdBytes() {
        java.lang.Object ref = menuItemId_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          menuItemId_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the MenuItem
       * within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_item_id = 1;</code>
       * @param value The menuItemId to set.
       * @return This builder for chaining.
       */
      public Builder setMenuItemId(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        menuItemId_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the MenuItem
       * within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_item_id = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearMenuItemId() {
        menuItemId_ = getDefaultInstance().getMenuItemId();
        bitField0_ = (bitField0_ & ~0x00000001);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the MenuItem
       * within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_item_id = 1;</code>
       * @param value The bytes for menuItemId to set.
       * @return This builder for chaining.
       */
      public Builder setMenuItemIdBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        menuItemId_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }

      private food.menu.v1.FoodMenu.TextField displayName_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> displayNameBuilder_;
      /**
       * <pre>
       * The name that can identify the MenuItem when a user is browsing the menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       * @return Whether the displayName field is set.
       */
      public boolean hasDisplayName() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * The name that can identify the MenuItem when a user is browsing the menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       * @return The displayName.
       */
      public food.menu.v1.FoodMenu.TextField getDisplayName() {
        if (displayNameBuilder_ == null) {
          return displayName_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : displayName_;
        } else {
          return displayNameBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * The name that can identify the MenuItem when a user is browsing the menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      public Builder setDisplayName(food.menu.v1.FoodMenu.TextField value) {
        if (displayNameBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          displayName_ = value;
        } else {
          displayNameBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name that can identify the MenuItem when a user is browsing the menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      public Builder setDisplayName(
          food.menu.v1.FoodMenu.TextField.Builder builderForValue) {
        if (displayNameBuilder_ == null) {
          displayName_ = builderForValue.build();
        } else {
          displayNameBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name that can identify the MenuItem when a user is browsing the menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      public Builder mergeDisplayName(food.menu.v1.FoodMenu.TextField value) {
        if (displayNameBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
            displayName_ != null &&
            displayName_ != food.menu.v1.FoodMenu.TextField.getDefaultInstance()) {
            getDisplayNameBuilder().mergeFrom(value);
          } else {
            displayName_ = value;
          }
        } else {
          displayNameBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name that can identify the MenuItem when a user is browsing the menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      public Builder clearDisplayName() {
        bitField0_ = (bitField0_ & ~0x00000002);
        displayName_ = null;
        if (displayNameBuilder_ != null) {
          displayNameBuilder_.dispose();
          displayNameBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name that can identify the MenuItem when a user is browsing the menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      public food.menu.v1.FoodMenu.TextField.Builder getDisplayNameBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getDisplayNameFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * The name that can identify the MenuItem when a user is browsing the menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      public food.menu.v1.FoodMenu.TextFieldOrBuilder getDisplayNameOrBuilder() {
        if (displayNameBuilder_ != null) {
          return displayNameBuilder_.getMessageOrBuilder();
        } else {
          return displayName_ == null ?
              food.menu.v1.FoodMenu.TextField.getDefaultInstance() : displayName_;
        }
      }
      /**
       * <pre>
       * The name that can identify the MenuItem when a user is browsing the menu.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField display_name = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> 
          getDisplayNameFieldBuilder() {
        if (displayNameBuilder_ == null) {
          displayNameBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder>(
                  getDisplayName(),
                  getParentForChildren(),
                  isClean());
          displayName_ = null;
        }
        return displayNameBuilder_;
      }

      private food.menu.v1.FoodMenu.TextField description_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> descriptionBuilder_;
      /**
       * <pre>
       * A description of the menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       * @return Whether the description field is set.
       */
      public boolean hasDescription() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <pre>
       * A description of the menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       * @return The description.
       */
      public food.menu.v1.FoodMenu.TextField getDescription() {
        if (descriptionBuilder_ == null) {
          return description_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : description_;
        } else {
          return descriptionBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * A description of the menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      public Builder setDescription(food.menu.v1.FoodMenu.TextField value) {
        if (descriptionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          description_ = value;
        } else {
          descriptionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * A description of the menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      public Builder setDescription(
          food.menu.v1.FoodMenu.TextField.Builder builderForValue) {
        if (descriptionBuilder_ == null) {
          description_ = builderForValue.build();
        } else {
          descriptionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * A description of the menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      public Builder mergeDescription(food.menu.v1.FoodMenu.TextField value) {
        if (descriptionBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
            description_ != null &&
            description_ != food.menu.v1.FoodMenu.TextField.getDefaultInstance()) {
            getDescriptionBuilder().mergeFrom(value);
          } else {
            description_ = value;
          }
        } else {
          descriptionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * A description of the menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      public Builder clearDescription() {
        bitField0_ = (bitField0_ & ~0x00000004);
        description_ = null;
        if (descriptionBuilder_ != null) {
          descriptionBuilder_.dispose();
          descriptionBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * A description of the menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      public food.menu.v1.FoodMenu.TextField.Builder getDescriptionBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getDescriptionFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * A description of the menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      public food.menu.v1.FoodMenu.TextFieldOrBuilder getDescriptionOrBuilder() {
        if (descriptionBuilder_ != null) {
          return descriptionBuilder_.getMessageOrBuilder();
        } else {
          return description_ == null ?
              food.menu.v1.FoodMenu.TextField.getDefaultInstance() : description_;
        }
      }
      /**
       * <pre>
       * A description of the menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> 
          getDescriptionFieldBuilder() {
        if (descriptionBuilder_ == null) {
          descriptionBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder>(
                  getDescription(),
                  getParentForChildren(),
                  isClean());
          description_ = null;
        }
        return descriptionBuilder_;
      }

      private java.util.List<food.menu.v1.FoodMenu.Image> images_ =
        java.util.Collections.emptyList();
      private void ensureImagesIsMutable() {
        if (!((bitField0_ & 0x00000008) != 0)) {
          images_ = new java.util.ArrayList<food.menu.v1.FoodMenu.Image>(images_);
          bitField0_ |= 0x00000008;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          food.menu.v1.FoodMenu.Image, food.menu.v1.FoodMenu.Image.Builder, food.menu.v1.FoodMenu.ImageOrBuilder> imagesBuilder_;

      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public java.util.List<food.menu.v1.FoodMenu.Image> getImagesList() {
        if (imagesBuilder_ == null) {
          return java.util.Collections.unmodifiableList(images_);
        } else {
          return imagesBuilder_.getMessageList();
        }
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public int getImagesCount() {
        if (imagesBuilder_ == null) {
          return images_.size();
        } else {
          return imagesBuilder_.getCount();
        }
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public food.menu.v1.FoodMenu.Image getImages(int index) {
        if (imagesBuilder_ == null) {
          return images_.get(index);
        } else {
          return imagesBuilder_.getMessage(index);
        }
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder setImages(
          int index, food.menu.v1.FoodMenu.Image value) {
        if (imagesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureImagesIsMutable();
          images_.set(index, value);
          onChanged();
        } else {
          imagesBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder setImages(
          int index, food.menu.v1.FoodMenu.Image.Builder builderForValue) {
        if (imagesBuilder_ == null) {
          ensureImagesIsMutable();
          images_.set(index, builderForValue.build());
          onChanged();
        } else {
          imagesBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder addImages(food.menu.v1.FoodMenu.Image value) {
        if (imagesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureImagesIsMutable();
          images_.add(value);
          onChanged();
        } else {
          imagesBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder addImages(
          int index, food.menu.v1.FoodMenu.Image value) {
        if (imagesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureImagesIsMutable();
          images_.add(index, value);
          onChanged();
        } else {
          imagesBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder addImages(
          food.menu.v1.FoodMenu.Image.Builder builderForValue) {
        if (imagesBuilder_ == null) {
          ensureImagesIsMutable();
          images_.add(builderForValue.build());
          onChanged();
        } else {
          imagesBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder addImages(
          int index, food.menu.v1.FoodMenu.Image.Builder builderForValue) {
        if (imagesBuilder_ == null) {
          ensureImagesIsMutable();
          images_.add(index, builderForValue.build());
          onChanged();
        } else {
          imagesBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder addAllImages(
          java.lang.Iterable<? extends food.menu.v1.FoodMenu.Image> values) {
        if (imagesBuilder_ == null) {
          ensureImagesIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, images_);
          onChanged();
        } else {
          imagesBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder clearImages() {
        if (imagesBuilder_ == null) {
          images_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000008);
          onChanged();
        } else {
          imagesBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public Builder removeImages(int index) {
        if (imagesBuilder_ == null) {
          ensureImagesIsMutable();
          images_.remove(index);
          onChanged();
        } else {
          imagesBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public food.menu.v1.FoodMenu.Image.Builder getImagesBuilder(
          int index) {
        return getImagesFieldBuilder().getBuilder(index);
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public food.menu.v1.FoodMenu.ImageOrBuilder getImagesOrBuilder(
          int index) {
        if (imagesBuilder_ == null) {
          return images_.get(index);  } else {
          return imagesBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public java.util.List<? extends food.menu.v1.FoodMenu.ImageOrBuilder> 
           getImagesOrBuilderList() {
        if (imagesBuilder_ != null) {
          return imagesBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(images_);
        }
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public food.menu.v1.FoodMenu.Image.Builder addImagesBuilder() {
        return getImagesFieldBuilder().addBuilder(
            food.menu.v1.FoodMenu.Image.getDefaultInstance());
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public food.menu.v1.FoodMenu.Image.Builder addImagesBuilder(
          int index) {
        return getImagesFieldBuilder().addBuilder(
            index, food.menu.v1.FoodMenu.Image.getDefaultInstance());
      }
      /**
       * <pre>
       * Image(s) of the menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Image images = 4;</code>
       */
      public java.util.List<food.menu.v1.FoodMenu.Image.Builder> 
           getImagesBuilderList() {
        return getImagesFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          food.menu.v1.FoodMenu.Image, food.menu.v1.FoodMenu.Image.Builder, food.menu.v1.FoodMenu.ImageOrBuilder> 
          getImagesFieldBuilder() {
        if (imagesBuilder_ == null) {
          imagesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              food.menu.v1.FoodMenu.Image, food.menu.v1.FoodMenu.Image.Builder, food.menu.v1.FoodMenu.ImageOrBuilder>(
                  images_,
                  ((bitField0_ & 0x00000008) != 0),
                  getParentForChildren(),
                  isClean());
          images_ = null;
        }
        return imagesBuilder_;
      }

      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.OfferSet, food.menu.v1.FoodMenu.OfferSet.Builder, food.menu.v1.FoodMenu.OfferSetOrBuilder> offerSetBuilder_;
      /**
       * <pre>
       * Available offers to purchase this food item.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
       * @return Whether the offerSet field is set.
       */
      @java.lang.Override
      public boolean hasOfferSet() {
        return pricingCase_ == 6;
      }
      /**
       * <pre>
       * Available offers to purchase this food item.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
       * @return The offerSet.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.OfferSet getOfferSet() {
        if (offerSetBuilder_ == null) {
          if (pricingCase_ == 6) {
            return (food.menu.v1.FoodMenu.OfferSet) pricing_;
          }
          return food.menu.v1.FoodMenu.OfferSet.getDefaultInstance();
        } else {
          if (pricingCase_ == 6) {
            return offerSetBuilder_.getMessage();
          }
          return food.menu.v1.FoodMenu.OfferSet.getDefaultInstance();
        }
      }
      /**
       * <pre>
       * Available offers to purchase this food item.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
       */
      public Builder setOfferSet(food.menu.v1.FoodMenu.OfferSet value) {
        if (offerSetBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          pricing_ = value;
          onChanged();
        } else {
          offerSetBuilder_.setMessage(value);
        }
        pricingCase_ = 6;
        return this;
      }
      /**
       * <pre>
       * Available offers to purchase this food item.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
       */
      public Builder setOfferSet(
          food.menu.v1.FoodMenu.OfferSet.Builder builderForValue) {
        if (offerSetBuilder_ == null) {
          pricing_ = builderForValue.build();
          onChanged();
        } else {
          offerSetBuilder_.setMessage(builderForValue.build());
        }
        pricingCase_ = 6;
        return this;
      }
      /**
       * <pre>
       * Available offers to purchase this food item.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
       */
      public Builder mergeOfferSet(food.menu.v1.FoodMenu.OfferSet value) {
        if (offerSetBuilder_ == null) {
          if (pricingCase_ == 6 &&
              pricing_ != food.menu.v1.FoodMenu.OfferSet.getDefaultInstance()) {
            pricing_ = food.menu.v1.FoodMenu.OfferSet.newBuilder((food.menu.v1.FoodMenu.OfferSet) pricing_)
                .mergeFrom(value).buildPartial();
          } else {
            pricing_ = value;
          }
          onChanged();
        } else {
          if (pricingCase_ == 6) {
            offerSetBuilder_.mergeFrom(value);
          } else {
            offerSetBuilder_.setMessage(value);
          }
        }
        pricingCase_ = 6;
        return this;
      }
      /**
       * <pre>
       * Available offers to purchase this food item.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
       */
      public Builder clearOfferSet() {
        if (offerSetBuilder_ == null) {
          if (pricingCase_ == 6) {
            pricingCase_ = 0;
            pricing_ = null;
            onChanged();
          }
        } else {
          if (pricingCase_ == 6) {
            pricingCase_ = 0;
            pricing_ = null;
          }
          offerSetBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       * Available offers to purchase this food item.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
       */
      public food.menu.v1.FoodMenu.OfferSet.Builder getOfferSetBuilder() {
        return getOfferSetFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Available offers to purchase this food item.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.OfferSetOrBuilder getOfferSetOrBuilder() {
        if ((pricingCase_ == 6) && (offerSetBuilder_ != null)) {
          return offerSetBuilder_.getMessageOrBuilder();
        } else {
          if (pricingCase_ == 6) {
            return (food.menu.v1.FoodMenu.OfferSet) pricing_;
          }
          return food.menu.v1.FoodMenu.OfferSet.getDefaultInstance();
        }
      }
      /**
       * <pre>
       * Available offers to purchase this food item.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 6;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.OfferSet, food.menu.v1.FoodMenu.OfferSet.Builder, food.menu.v1.FoodMenu.OfferSetOrBuilder> 
          getOfferSetFieldBuilder() {
        if (offerSetBuilder_ == null) {
          if (!(pricingCase_ == 6)) {
            pricing_ = food.menu.v1.FoodMenu.OfferSet.getDefaultInstance();
          }
          offerSetBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.OfferSet, food.menu.v1.FoodMenu.OfferSet.Builder, food.menu.v1.FoodMenu.OfferSetOrBuilder>(
                  (food.menu.v1.FoodMenu.OfferSet) pricing_,
                  getParentForChildren(),
                  isClean());
          pricing_ = null;
        }
        pricingCase_ = 6;
        onChanged();
        return offerSetBuilder_;
      }

      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet, food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.Builder, food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSetOrBuilder> menuItemOptionSetBuilder_;
      /**
       * <pre>
       * Available options for this menu item.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
       * @return Whether the menuItemOptionSet field is set.
       */
      @java.lang.Override
      public boolean hasMenuItemOptionSet() {
        return pricingCase_ == 7;
      }
      /**
       * <pre>
       * Available options for this menu item.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
       * @return The menuItemOptionSet.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet getMenuItemOptionSet() {
        if (menuItemOptionSetBuilder_ == null) {
          if (pricingCase_ == 7) {
            return (food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet) pricing_;
          }
          return food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.getDefaultInstance();
        } else {
          if (pricingCase_ == 7) {
            return menuItemOptionSetBuilder_.getMessage();
          }
          return food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.getDefaultInstance();
        }
      }
      /**
       * <pre>
       * Available options for this menu item.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
       */
      public Builder setMenuItemOptionSet(food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet value) {
        if (menuItemOptionSetBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          pricing_ = value;
          onChanged();
        } else {
          menuItemOptionSetBuilder_.setMessage(value);
        }
        pricingCase_ = 7;
        return this;
      }
      /**
       * <pre>
       * Available options for this menu item.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
       */
      public Builder setMenuItemOptionSet(
          food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.Builder builderForValue) {
        if (menuItemOptionSetBuilder_ == null) {
          pricing_ = builderForValue.build();
          onChanged();
        } else {
          menuItemOptionSetBuilder_.setMessage(builderForValue.build());
        }
        pricingCase_ = 7;
        return this;
      }
      /**
       * <pre>
       * Available options for this menu item.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
       */
      public Builder mergeMenuItemOptionSet(food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet value) {
        if (menuItemOptionSetBuilder_ == null) {
          if (pricingCase_ == 7 &&
              pricing_ != food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.getDefaultInstance()) {
            pricing_ = food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.newBuilder((food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet) pricing_)
                .mergeFrom(value).buildPartial();
          } else {
            pricing_ = value;
          }
          onChanged();
        } else {
          if (pricingCase_ == 7) {
            menuItemOptionSetBuilder_.mergeFrom(value);
          } else {
            menuItemOptionSetBuilder_.setMessage(value);
          }
        }
        pricingCase_ = 7;
        return this;
      }
      /**
       * <pre>
       * Available options for this menu item.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
       */
      public Builder clearMenuItemOptionSet() {
        if (menuItemOptionSetBuilder_ == null) {
          if (pricingCase_ == 7) {
            pricingCase_ = 0;
            pricing_ = null;
            onChanged();
          }
        } else {
          if (pricingCase_ == 7) {
            pricingCase_ = 0;
            pricing_ = null;
          }
          menuItemOptionSetBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       * Available options for this menu item.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
       */
      public food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.Builder getMenuItemOptionSetBuilder() {
        return getMenuItemOptionSetFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Available options for this menu item.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSetOrBuilder getMenuItemOptionSetOrBuilder() {
        if ((pricingCase_ == 7) && (menuItemOptionSetBuilder_ != null)) {
          return menuItemOptionSetBuilder_.getMessageOrBuilder();
        } else {
          if (pricingCase_ == 7) {
            return (food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet) pricing_;
          }
          return food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.getDefaultInstance();
        }
      }
      /**
       * <pre>
       * Available options for this menu item.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItem.MenuItemOptionSet menu_item_option_set = 7;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet, food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.Builder, food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSetOrBuilder> 
          getMenuItemOptionSetFieldBuilder() {
        if (menuItemOptionSetBuilder_ == null) {
          if (!(pricingCase_ == 7)) {
            pricing_ = food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.getDefaultInstance();
          }
          menuItemOptionSetBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet, food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet.Builder, food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSetOrBuilder>(
                  (food.menu.v1.FoodMenu.MenuItem.MenuItemOptionSet) pricing_,
                  getParentForChildren(),
                  isClean());
          pricing_ = null;
        }
        pricingCase_ = 7;
        onChanged();
        return menuItemOptionSetBuilder_;
      }

      private food.menu.v1.FoodMenu.MenuItemAttributes itemAttributes_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuItemAttributes, food.menu.v1.FoodMenu.MenuItemAttributes.Builder, food.menu.v1.FoodMenu.MenuItemAttributesOrBuilder> itemAttributesBuilder_;
      /**
       * <pre>
       * Attributes about this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
       * @return Whether the itemAttributes field is set.
       */
      public boolean hasItemAttributes() {
        return ((bitField0_ & 0x00000040) != 0);
      }
      /**
       * <pre>
       * Attributes about this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
       * @return The itemAttributes.
       */
      public food.menu.v1.FoodMenu.MenuItemAttributes getItemAttributes() {
        if (itemAttributesBuilder_ == null) {
          return itemAttributes_ == null ? food.menu.v1.FoodMenu.MenuItemAttributes.getDefaultInstance() : itemAttributes_;
        } else {
          return itemAttributesBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Attributes about this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
       */
      public Builder setItemAttributes(food.menu.v1.FoodMenu.MenuItemAttributes value) {
        if (itemAttributesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          itemAttributes_ = value;
        } else {
          itemAttributesBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000040;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Attributes about this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
       */
      public Builder setItemAttributes(
          food.menu.v1.FoodMenu.MenuItemAttributes.Builder builderForValue) {
        if (itemAttributesBuilder_ == null) {
          itemAttributes_ = builderForValue.build();
        } else {
          itemAttributesBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000040;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Attributes about this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
       */
      public Builder mergeItemAttributes(food.menu.v1.FoodMenu.MenuItemAttributes value) {
        if (itemAttributesBuilder_ == null) {
          if (((bitField0_ & 0x00000040) != 0) &&
            itemAttributes_ != null &&
            itemAttributes_ != food.menu.v1.FoodMenu.MenuItemAttributes.getDefaultInstance()) {
            getItemAttributesBuilder().mergeFrom(value);
          } else {
            itemAttributes_ = value;
          }
        } else {
          itemAttributesBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000040;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Attributes about this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
       */
      public Builder clearItemAttributes() {
        bitField0_ = (bitField0_ & ~0x00000040);
        itemAttributes_ = null;
        if (itemAttributesBuilder_ != null) {
          itemAttributesBuilder_.dispose();
          itemAttributesBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Attributes about this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
       */
      public food.menu.v1.FoodMenu.MenuItemAttributes.Builder getItemAttributesBuilder() {
        bitField0_ |= 0x00000040;
        onChanged();
        return getItemAttributesFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Attributes about this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
       */
      public food.menu.v1.FoodMenu.MenuItemAttributesOrBuilder getItemAttributesOrBuilder() {
        if (itemAttributesBuilder_ != null) {
          return itemAttributesBuilder_.getMessageOrBuilder();
        } else {
          return itemAttributes_ == null ?
              food.menu.v1.FoodMenu.MenuItemAttributes.getDefaultInstance() : itemAttributes_;
        }
      }
      /**
       * <pre>
       * Attributes about this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 8;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuItemAttributes, food.menu.v1.FoodMenu.MenuItemAttributes.Builder, food.menu.v1.FoodMenu.MenuItemAttributesOrBuilder> 
          getItemAttributesFieldBuilder() {
        if (itemAttributesBuilder_ == null) {
          itemAttributesBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.MenuItemAttributes, food.menu.v1.FoodMenu.MenuItemAttributes.Builder, food.menu.v1.FoodMenu.MenuItemAttributesOrBuilder>(
                  getItemAttributes(),
                  getParentForChildren(),
                  isClean());
          itemAttributes_ = null;
        }
        return itemAttributesBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.MenuItem)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.MenuItem)
    private static final food.menu.v1.FoodMenu.MenuItem DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.MenuItem();
    }

    public static food.menu.v1.FoodMenu.MenuItem getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<MenuItem>
        PARSER = new com.google.protobuf.AbstractParser<MenuItem>() {
      @java.lang.Override
      public MenuItem parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<MenuItem> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<MenuItem> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItem getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface MenuItemOptionOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.MenuItemOption)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * An opaque string from an partner which uniquely identifies the
     * MenuItemOption within the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_item_option_id = 9;</code>
     * @return The menuItemOptionId.
     */
    java.lang.String getMenuItemOptionId();
    /**
     * <pre>
     * An opaque string from an partner which uniquely identifies the
     * MenuItemOption within the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_item_option_id = 9;</code>
     * @return The bytes for menuItemOptionId.
     */
    com.google.protobuf.ByteString
        getMenuItemOptionIdBytes();

    /**
     * <pre>
     * Option property and value e.g. Size: Small.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
     * @return Whether the value field is set.
     */
    boolean hasValue();
    /**
     * <pre>
     * Option property and value e.g. Size: Small.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
     * @return The value.
     */
    food.menu.v1.FoodMenu.MenuItemOptionProperty getValue();
    /**
     * <pre>
     * Option property and value e.g. Size: Small.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
     */
    food.menu.v1.FoodMenu.MenuItemOptionPropertyOrBuilder getValueOrBuilder();

    /**
     * <pre>
     * Available offers to purchase this menu item option.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
     * @return Whether the offerSet field is set.
     */
    boolean hasOfferSet();
    /**
     * <pre>
     * Available offers to purchase this menu item option.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
     * @return The offerSet.
     */
    food.menu.v1.FoodMenu.OfferSet getOfferSet();
    /**
     * <pre>
     * Available offers to purchase this menu item option.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
     */
    food.menu.v1.FoodMenu.OfferSetOrBuilder getOfferSetOrBuilder();

    /**
     * <pre>
     * Attributes about this menu item option.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
     * @return Whether the itemAttributes field is set.
     */
    boolean hasItemAttributes();
    /**
     * <pre>
     * Attributes about this menu item option.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
     * @return The itemAttributes.
     */
    food.menu.v1.FoodMenu.MenuItemAttributes getItemAttributes();
    /**
     * <pre>
     * Attributes about this menu item option.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
     */
    food.menu.v1.FoodMenu.MenuItemAttributesOrBuilder getItemAttributesOrBuilder();
  }
  /**
   * <pre>
   * Describes choices that a user would be required to make when selecting a
   * dish / combo. The user must select an option, otherwise the order is
   * considered invalid (e.g. the user must choose small, medium, or large for a
   * pizza).
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.MenuItemOption}
   */
  public static final class MenuItemOption extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.MenuItemOption)
      MenuItemOptionOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use MenuItemOption.newBuilder() to construct.
    private MenuItemOption(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private MenuItemOption() {
      menuItemOptionId_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new MenuItemOption();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemOption_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemOption_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.MenuItemOption.class, food.menu.v1.FoodMenu.MenuItemOption.Builder.class);
    }

    public static final int MENU_ITEM_OPTION_ID_FIELD_NUMBER = 9;
    @SuppressWarnings("serial")
    private volatile java.lang.Object menuItemOptionId_ = "";
    /**
     * <pre>
     * An opaque string from an partner which uniquely identifies the
     * MenuItemOption within the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_item_option_id = 9;</code>
     * @return The menuItemOptionId.
     */
    @java.lang.Override
    public java.lang.String getMenuItemOptionId() {
      java.lang.Object ref = menuItemOptionId_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        menuItemOptionId_ = s;
        return s;
      }
    }
    /**
     * <pre>
     * An opaque string from an partner which uniquely identifies the
     * MenuItemOption within the partner feed.
     * Required.
     * </pre>
     *
     * <code>string menu_item_option_id = 9;</code>
     * @return The bytes for menuItemOptionId.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getMenuItemOptionIdBytes() {
      java.lang.Object ref = menuItemOptionId_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        menuItemOptionId_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int VALUE_FIELD_NUMBER = 2;
    private food.menu.v1.FoodMenu.MenuItemOptionProperty value_;
    /**
     * <pre>
     * Option property and value e.g. Size: Small.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
     * @return Whether the value field is set.
     */
    @java.lang.Override
    public boolean hasValue() {
      return value_ != null;
    }
    /**
     * <pre>
     * Option property and value e.g. Size: Small.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
     * @return The value.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItemOptionProperty getValue() {
      return value_ == null ? food.menu.v1.FoodMenu.MenuItemOptionProperty.getDefaultInstance() : value_;
    }
    /**
     * <pre>
     * Option property and value e.g. Size: Small.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItemOptionPropertyOrBuilder getValueOrBuilder() {
      return value_ == null ? food.menu.v1.FoodMenu.MenuItemOptionProperty.getDefaultInstance() : value_;
    }

    public static final int OFFER_SET_FIELD_NUMBER = 4;
    private food.menu.v1.FoodMenu.OfferSet offerSet_;
    /**
     * <pre>
     * Available offers to purchase this menu item option.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
     * @return Whether the offerSet field is set.
     */
    @java.lang.Override
    public boolean hasOfferSet() {
      return offerSet_ != null;
    }
    /**
     * <pre>
     * Available offers to purchase this menu item option.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
     * @return The offerSet.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.OfferSet getOfferSet() {
      return offerSet_ == null ? food.menu.v1.FoodMenu.OfferSet.getDefaultInstance() : offerSet_;
    }
    /**
     * <pre>
     * Available offers to purchase this menu item option.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.OfferSetOrBuilder getOfferSetOrBuilder() {
      return offerSet_ == null ? food.menu.v1.FoodMenu.OfferSet.getDefaultInstance() : offerSet_;
    }

    public static final int ITEM_ATTRIBUTES_FIELD_NUMBER = 5;
    private food.menu.v1.FoodMenu.MenuItemAttributes itemAttributes_;
    /**
     * <pre>
     * Attributes about this menu item option.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
     * @return Whether the itemAttributes field is set.
     */
    @java.lang.Override
    public boolean hasItemAttributes() {
      return itemAttributes_ != null;
    }
    /**
     * <pre>
     * Attributes about this menu item option.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
     * @return The itemAttributes.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItemAttributes getItemAttributes() {
      return itemAttributes_ == null ? food.menu.v1.FoodMenu.MenuItemAttributes.getDefaultInstance() : itemAttributes_;
    }
    /**
     * <pre>
     * Attributes about this menu item option.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItemAttributesOrBuilder getItemAttributesOrBuilder() {
      return itemAttributes_ == null ? food.menu.v1.FoodMenu.MenuItemAttributes.getDefaultInstance() : itemAttributes_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (value_ != null) {
        output.writeMessage(2, getValue());
      }
      if (offerSet_ != null) {
        output.writeMessage(4, getOfferSet());
      }
      if (itemAttributes_ != null) {
        output.writeMessage(5, getItemAttributes());
      }
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(menuItemOptionId_)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 9, menuItemOptionId_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (value_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getValue());
      }
      if (offerSet_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, getOfferSet());
      }
      if (itemAttributes_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(5, getItemAttributes());
      }
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(menuItemOptionId_)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(9, menuItemOptionId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.MenuItemOption)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.MenuItemOption other = (food.menu.v1.FoodMenu.MenuItemOption) obj;

      if (!getMenuItemOptionId()
          .equals(other.getMenuItemOptionId())) return false;
      if (hasValue() != other.hasValue()) return false;
      if (hasValue()) {
        if (!getValue()
            .equals(other.getValue())) return false;
      }
      if (hasOfferSet() != other.hasOfferSet()) return false;
      if (hasOfferSet()) {
        if (!getOfferSet()
            .equals(other.getOfferSet())) return false;
      }
      if (hasItemAttributes() != other.hasItemAttributes()) return false;
      if (hasItemAttributes()) {
        if (!getItemAttributes()
            .equals(other.getItemAttributes())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      hash = (37 * hash) + MENU_ITEM_OPTION_ID_FIELD_NUMBER;
      hash = (53 * hash) + getMenuItemOptionId().hashCode();
      if (hasValue()) {
        hash = (37 * hash) + VALUE_FIELD_NUMBER;
        hash = (53 * hash) + getValue().hashCode();
      }
      if (hasOfferSet()) {
        hash = (37 * hash) + OFFER_SET_FIELD_NUMBER;
        hash = (53 * hash) + getOfferSet().hashCode();
      }
      if (hasItemAttributes()) {
        hash = (37 * hash) + ITEM_ATTRIBUTES_FIELD_NUMBER;
        hash = (53 * hash) + getItemAttributes().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.MenuItemOption parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuItemOption parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemOption parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuItemOption parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemOption parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuItemOption parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemOption parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuItemOption parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemOption parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuItemOption parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemOption parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuItemOption parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.MenuItemOption prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Describes choices that a user would be required to make when selecting a
     * dish / combo. The user must select an option, otherwise the order is
     * considered invalid (e.g. the user must choose small, medium, or large for a
     * pizza).
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.MenuItemOption}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.MenuItemOption)
        food.menu.v1.FoodMenu.MenuItemOptionOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemOption_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemOption_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.MenuItemOption.class, food.menu.v1.FoodMenu.MenuItemOption.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.MenuItemOption.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        menuItemOptionId_ = "";
        value_ = null;
        if (valueBuilder_ != null) {
          valueBuilder_.dispose();
          valueBuilder_ = null;
        }
        offerSet_ = null;
        if (offerSetBuilder_ != null) {
          offerSetBuilder_.dispose();
          offerSetBuilder_ = null;
        }
        itemAttributes_ = null;
        if (itemAttributesBuilder_ != null) {
          itemAttributesBuilder_.dispose();
          itemAttributesBuilder_ = null;
        }
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemOption_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemOption getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.MenuItemOption.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemOption build() {
        food.menu.v1.FoodMenu.MenuItemOption result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemOption buildPartial() {
        food.menu.v1.FoodMenu.MenuItemOption result = new food.menu.v1.FoodMenu.MenuItemOption(this);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartial0(food.menu.v1.FoodMenu.MenuItemOption result) {
        int from_bitField0_ = bitField0_;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.menuItemOptionId_ = menuItemOptionId_;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.value_ = valueBuilder_ == null
              ? value_
              : valueBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.offerSet_ = offerSetBuilder_ == null
              ? offerSet_
              : offerSetBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.itemAttributes_ = itemAttributesBuilder_ == null
              ? itemAttributes_
              : itemAttributesBuilder_.build();
        }
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.MenuItemOption) {
          return mergeFrom((food.menu.v1.FoodMenu.MenuItemOption)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.MenuItemOption other) {
        if (other == food.menu.v1.FoodMenu.MenuItemOption.getDefaultInstance()) return this;
        if (!other.getMenuItemOptionId().isEmpty()) {
          menuItemOptionId_ = other.menuItemOptionId_;
          bitField0_ |= 0x00000001;
          onChanged();
        }
        if (other.hasValue()) {
          mergeValue(other.getValue());
        }
        if (other.hasOfferSet()) {
          mergeOfferSet(other.getOfferSet());
        }
        if (other.hasItemAttributes()) {
          mergeItemAttributes(other.getItemAttributes());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 18: {
                input.readMessage(
                    getValueFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 34: {
                input.readMessage(
                    getOfferSetFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 34
              case 42: {
                input.readMessage(
                    getItemAttributesFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000008;
                break;
              } // case 42
              case 74: {
                menuItemOptionId_ = input.readStringRequireUtf8();
                bitField0_ |= 0x00000001;
                break;
              } // case 74
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object menuItemOptionId_ = "";
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the
       * MenuItemOption within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_item_option_id = 9;</code>
       * @return The menuItemOptionId.
       */
      public java.lang.String getMenuItemOptionId() {
        java.lang.Object ref = menuItemOptionId_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          menuItemOptionId_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the
       * MenuItemOption within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_item_option_id = 9;</code>
       * @return The bytes for menuItemOptionId.
       */
      public com.google.protobuf.ByteString
          getMenuItemOptionIdBytes() {
        java.lang.Object ref = menuItemOptionId_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          menuItemOptionId_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the
       * MenuItemOption within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_item_option_id = 9;</code>
       * @param value The menuItemOptionId to set.
       * @return This builder for chaining.
       */
      public Builder setMenuItemOptionId(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        menuItemOptionId_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the
       * MenuItemOption within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_item_option_id = 9;</code>
       * @return This builder for chaining.
       */
      public Builder clearMenuItemOptionId() {
        menuItemOptionId_ = getDefaultInstance().getMenuItemOptionId();
        bitField0_ = (bitField0_ & ~0x00000001);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * An opaque string from an partner which uniquely identifies the
       * MenuItemOption within the partner feed.
       * Required.
       * </pre>
       *
       * <code>string menu_item_option_id = 9;</code>
       * @param value The bytes for menuItemOptionId to set.
       * @return This builder for chaining.
       */
      public Builder setMenuItemOptionIdBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        menuItemOptionId_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }

      private food.menu.v1.FoodMenu.MenuItemOptionProperty value_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuItemOptionProperty, food.menu.v1.FoodMenu.MenuItemOptionProperty.Builder, food.menu.v1.FoodMenu.MenuItemOptionPropertyOrBuilder> valueBuilder_;
      /**
       * <pre>
       * Option property and value e.g. Size: Small.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
       * @return Whether the value field is set.
       */
      public boolean hasValue() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * Option property and value e.g. Size: Small.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
       * @return The value.
       */
      public food.menu.v1.FoodMenu.MenuItemOptionProperty getValue() {
        if (valueBuilder_ == null) {
          return value_ == null ? food.menu.v1.FoodMenu.MenuItemOptionProperty.getDefaultInstance() : value_;
        } else {
          return valueBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Option property and value e.g. Size: Small.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
       */
      public Builder setValue(food.menu.v1.FoodMenu.MenuItemOptionProperty value) {
        if (valueBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          value_ = value;
        } else {
          valueBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Option property and value e.g. Size: Small.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
       */
      public Builder setValue(
          food.menu.v1.FoodMenu.MenuItemOptionProperty.Builder builderForValue) {
        if (valueBuilder_ == null) {
          value_ = builderForValue.build();
        } else {
          valueBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Option property and value e.g. Size: Small.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
       */
      public Builder mergeValue(food.menu.v1.FoodMenu.MenuItemOptionProperty value) {
        if (valueBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
            value_ != null &&
            value_ != food.menu.v1.FoodMenu.MenuItemOptionProperty.getDefaultInstance()) {
            getValueBuilder().mergeFrom(value);
          } else {
            value_ = value;
          }
        } else {
          valueBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Option property and value e.g. Size: Small.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
       */
      public Builder clearValue() {
        bitField0_ = (bitField0_ & ~0x00000002);
        value_ = null;
        if (valueBuilder_ != null) {
          valueBuilder_.dispose();
          valueBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Option property and value e.g. Size: Small.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
       */
      public food.menu.v1.FoodMenu.MenuItemOptionProperty.Builder getValueBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getValueFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Option property and value e.g. Size: Small.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
       */
      public food.menu.v1.FoodMenu.MenuItemOptionPropertyOrBuilder getValueOrBuilder() {
        if (valueBuilder_ != null) {
          return valueBuilder_.getMessageOrBuilder();
        } else {
          return value_ == null ?
              food.menu.v1.FoodMenu.MenuItemOptionProperty.getDefaultInstance() : value_;
        }
      }
      /**
       * <pre>
       * Option property and value e.g. Size: Small.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty value = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuItemOptionProperty, food.menu.v1.FoodMenu.MenuItemOptionProperty.Builder, food.menu.v1.FoodMenu.MenuItemOptionPropertyOrBuilder> 
          getValueFieldBuilder() {
        if (valueBuilder_ == null) {
          valueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.MenuItemOptionProperty, food.menu.v1.FoodMenu.MenuItemOptionProperty.Builder, food.menu.v1.FoodMenu.MenuItemOptionPropertyOrBuilder>(
                  getValue(),
                  getParentForChildren(),
                  isClean());
          value_ = null;
        }
        return valueBuilder_;
      }

      private food.menu.v1.FoodMenu.OfferSet offerSet_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.OfferSet, food.menu.v1.FoodMenu.OfferSet.Builder, food.menu.v1.FoodMenu.OfferSetOrBuilder> offerSetBuilder_;
      /**
       * <pre>
       * Available offers to purchase this menu item option.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
       * @return Whether the offerSet field is set.
       */
      public boolean hasOfferSet() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <pre>
       * Available offers to purchase this menu item option.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
       * @return The offerSet.
       */
      public food.menu.v1.FoodMenu.OfferSet getOfferSet() {
        if (offerSetBuilder_ == null) {
          return offerSet_ == null ? food.menu.v1.FoodMenu.OfferSet.getDefaultInstance() : offerSet_;
        } else {
          return offerSetBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Available offers to purchase this menu item option.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
       */
      public Builder setOfferSet(food.menu.v1.FoodMenu.OfferSet value) {
        if (offerSetBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          offerSet_ = value;
        } else {
          offerSetBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Available offers to purchase this menu item option.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
       */
      public Builder setOfferSet(
          food.menu.v1.FoodMenu.OfferSet.Builder builderForValue) {
        if (offerSetBuilder_ == null) {
          offerSet_ = builderForValue.build();
        } else {
          offerSetBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Available offers to purchase this menu item option.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
       */
      public Builder mergeOfferSet(food.menu.v1.FoodMenu.OfferSet value) {
        if (offerSetBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
            offerSet_ != null &&
            offerSet_ != food.menu.v1.FoodMenu.OfferSet.getDefaultInstance()) {
            getOfferSetBuilder().mergeFrom(value);
          } else {
            offerSet_ = value;
          }
        } else {
          offerSetBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Available offers to purchase this menu item option.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
       */
      public Builder clearOfferSet() {
        bitField0_ = (bitField0_ & ~0x00000004);
        offerSet_ = null;
        if (offerSetBuilder_ != null) {
          offerSetBuilder_.dispose();
          offerSetBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Available offers to purchase this menu item option.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
       */
      public food.menu.v1.FoodMenu.OfferSet.Builder getOfferSetBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getOfferSetFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Available offers to purchase this menu item option.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
       */
      public food.menu.v1.FoodMenu.OfferSetOrBuilder getOfferSetOrBuilder() {
        if (offerSetBuilder_ != null) {
          return offerSetBuilder_.getMessageOrBuilder();
        } else {
          return offerSet_ == null ?
              food.menu.v1.FoodMenu.OfferSet.getDefaultInstance() : offerSet_;
        }
      }
      /**
       * <pre>
       * Available offers to purchase this menu item option.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.OfferSet offer_set = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.OfferSet, food.menu.v1.FoodMenu.OfferSet.Builder, food.menu.v1.FoodMenu.OfferSetOrBuilder> 
          getOfferSetFieldBuilder() {
        if (offerSetBuilder_ == null) {
          offerSetBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.OfferSet, food.menu.v1.FoodMenu.OfferSet.Builder, food.menu.v1.FoodMenu.OfferSetOrBuilder>(
                  getOfferSet(),
                  getParentForChildren(),
                  isClean());
          offerSet_ = null;
        }
        return offerSetBuilder_;
      }

      private food.menu.v1.FoodMenu.MenuItemAttributes itemAttributes_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuItemAttributes, food.menu.v1.FoodMenu.MenuItemAttributes.Builder, food.menu.v1.FoodMenu.MenuItemAttributesOrBuilder> itemAttributesBuilder_;
      /**
       * <pre>
       * Attributes about this menu item option.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
       * @return Whether the itemAttributes field is set.
       */
      public boolean hasItemAttributes() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <pre>
       * Attributes about this menu item option.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
       * @return The itemAttributes.
       */
      public food.menu.v1.FoodMenu.MenuItemAttributes getItemAttributes() {
        if (itemAttributesBuilder_ == null) {
          return itemAttributes_ == null ? food.menu.v1.FoodMenu.MenuItemAttributes.getDefaultInstance() : itemAttributes_;
        } else {
          return itemAttributesBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Attributes about this menu item option.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
       */
      public Builder setItemAttributes(food.menu.v1.FoodMenu.MenuItemAttributes value) {
        if (itemAttributesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          itemAttributes_ = value;
        } else {
          itemAttributesBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Attributes about this menu item option.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
       */
      public Builder setItemAttributes(
          food.menu.v1.FoodMenu.MenuItemAttributes.Builder builderForValue) {
        if (itemAttributesBuilder_ == null) {
          itemAttributes_ = builderForValue.build();
        } else {
          itemAttributesBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Attributes about this menu item option.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
       */
      public Builder mergeItemAttributes(food.menu.v1.FoodMenu.MenuItemAttributes value) {
        if (itemAttributesBuilder_ == null) {
          if (((bitField0_ & 0x00000008) != 0) &&
            itemAttributes_ != null &&
            itemAttributes_ != food.menu.v1.FoodMenu.MenuItemAttributes.getDefaultInstance()) {
            getItemAttributesBuilder().mergeFrom(value);
          } else {
            itemAttributes_ = value;
          }
        } else {
          itemAttributesBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Attributes about this menu item option.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
       */
      public Builder clearItemAttributes() {
        bitField0_ = (bitField0_ & ~0x00000008);
        itemAttributes_ = null;
        if (itemAttributesBuilder_ != null) {
          itemAttributesBuilder_.dispose();
          itemAttributesBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Attributes about this menu item option.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
       */
      public food.menu.v1.FoodMenu.MenuItemAttributes.Builder getItemAttributesBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getItemAttributesFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Attributes about this menu item option.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
       */
      public food.menu.v1.FoodMenu.MenuItemAttributesOrBuilder getItemAttributesOrBuilder() {
        if (itemAttributesBuilder_ != null) {
          return itemAttributesBuilder_.getMessageOrBuilder();
        } else {
          return itemAttributes_ == null ?
              food.menu.v1.FoodMenu.MenuItemAttributes.getDefaultInstance() : itemAttributes_;
        }
      }
      /**
       * <pre>
       * Attributes about this menu item option.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemAttributes item_attributes = 5;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.MenuItemAttributes, food.menu.v1.FoodMenu.MenuItemAttributes.Builder, food.menu.v1.FoodMenu.MenuItemAttributesOrBuilder> 
          getItemAttributesFieldBuilder() {
        if (itemAttributesBuilder_ == null) {
          itemAttributesBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.MenuItemAttributes, food.menu.v1.FoodMenu.MenuItemAttributes.Builder, food.menu.v1.FoodMenu.MenuItemAttributesOrBuilder>(
                  getItemAttributes(),
                  getParentForChildren(),
                  isClean());
          itemAttributes_ = null;
        }
        return itemAttributesBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.MenuItemOption)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.MenuItemOption)
    private static final food.menu.v1.FoodMenu.MenuItemOption DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.MenuItemOption();
    }

    public static food.menu.v1.FoodMenu.MenuItemOption getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<MenuItemOption>
        PARSER = new com.google.protobuf.AbstractParser<MenuItemOption>() {
      @java.lang.Override
      public MenuItemOption parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<MenuItemOption> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<MenuItemOption> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItemOption getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface MenuItemAttributesOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.MenuItemAttributes)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * Number of servings available in a given menu item.
     * Optional.
     * </pre>
     *
     * <code>optional int32 number_of_servings = 1;</code>
     * @return Whether the numberOfServings field is set.
     */
    boolean hasNumberOfServings();
    /**
     * <pre>
     * Number of servings available in a given menu item.
     * Optional.
     * </pre>
     *
     * <code>optional int32 number_of_servings = 1;</code>
     * @return The numberOfServings.
     */
    int getNumberOfServings();

    /**
     * <pre>
     * Describes all the nutritional information of the item, e.g. calories, fat
     * content.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
     * @return Whether the nutritionInformation field is set.
     */
    boolean hasNutritionInformation();
    /**
     * <pre>
     * Describes all the nutritional information of the item, e.g. calories, fat
     * content.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
     * @return The nutritionInformation.
     */
    food.menu.v1.FoodMenu.NutritionInformation getNutritionInformation();
    /**
     * <pre>
     * Describes all the nutritional information of the item, e.g. calories, fat
     * content.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
     */
    food.menu.v1.FoodMenu.NutritionInformationOrBuilder getNutritionInformationOrBuilder();

    /**
     * <pre>
     * The dietary restrictions that this menu item complies with.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
     * @return A list containing the suitableDiets.
     */
    java.util.List<food.menu.v1.FoodMenu.DietaryRestriction> getSuitableDietsList();
    /**
     * <pre>
     * The dietary restrictions that this menu item complies with.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
     * @return The count of suitableDiets.
     */
    int getSuitableDietsCount();
    /**
     * <pre>
     * The dietary restrictions that this menu item complies with.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
     * @param index The index of the element to return.
     * @return The suitableDiets at the given index.
     */
    food.menu.v1.FoodMenu.DietaryRestriction getSuitableDiets(int index);
    /**
     * <pre>
     * The dietary restrictions that this menu item complies with.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
     * @return A list containing the enum numeric values on the wire for suitableDiets.
     */
    java.util.List<java.lang.Integer>
    getSuitableDietsValueList();
    /**
     * <pre>
     * The dietary restrictions that this menu item complies with.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
     * @param index The index of the value to return.
     * @return The enum numeric value on the wire of suitableDiets at the given index.
     */
    int getSuitableDietsValue(int index);

    /**
     * <pre>
     * Additives of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Additive additive = 4;</code>
     */
    java.util.List<food.menu.v1.FoodMenu.Additive> 
        getAdditiveList();
    /**
     * <pre>
     * Additives of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Additive additive = 4;</code>
     */
    food.menu.v1.FoodMenu.Additive getAdditive(int index);
    /**
     * <pre>
     * Additives of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Additive additive = 4;</code>
     */
    int getAdditiveCount();
    /**
     * <pre>
     * Additives of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Additive additive = 4;</code>
     */
    java.util.List<? extends food.menu.v1.FoodMenu.AdditiveOrBuilder> 
        getAdditiveOrBuilderList();
    /**
     * <pre>
     * Additives of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Additive additive = 4;</code>
     */
    food.menu.v1.FoodMenu.AdditiveOrBuilder getAdditiveOrBuilder(
        int index);

    /**
     * <pre>
     * Allergens of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
     */
    java.util.List<food.menu.v1.FoodMenu.Allergen> 
        getAllergenList();
    /**
     * <pre>
     * Allergens of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
     */
    food.menu.v1.FoodMenu.Allergen getAllergen(int index);
    /**
     * <pre>
     * Allergens of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
     */
    int getAllergenCount();
    /**
     * <pre>
     * Allergens of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
     */
    java.util.List<? extends food.menu.v1.FoodMenu.AllergenOrBuilder> 
        getAllergenOrBuilderList();
    /**
     * <pre>
     * Allergens of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
     */
    food.menu.v1.FoodMenu.AllergenOrBuilder getAllergenOrBuilder(
        int index);

    /**
     * <pre>
     * Packaging and recycling information of this menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
     * @return Whether the packagingDepositInfo field is set.
     */
    boolean hasPackagingDepositInfo();
    /**
     * <pre>
     * Packaging and recycling information of this menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
     * @return The packagingDepositInfo.
     */
    food.menu.v1.FoodMenu.DepositInfo getPackagingDepositInfo();
    /**
     * <pre>
     * Packaging and recycling information of this menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
     */
    food.menu.v1.FoodMenu.DepositInfoOrBuilder getPackagingDepositInfoOrBuilder();
  }
  /**
   * <pre>
   * Describes attributes about a particular menu item or option.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.MenuItemAttributes}
   */
  public static final class MenuItemAttributes extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.MenuItemAttributes)
      MenuItemAttributesOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use MenuItemAttributes.newBuilder() to construct.
    private MenuItemAttributes(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private MenuItemAttributes() {
      suitableDiets_ = java.util.Collections.emptyList();
      additive_ = java.util.Collections.emptyList();
      allergen_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new MenuItemAttributes();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemAttributes_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemAttributes_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.MenuItemAttributes.class, food.menu.v1.FoodMenu.MenuItemAttributes.Builder.class);
    }

    private int bitField0_;
    public static final int NUMBER_OF_SERVINGS_FIELD_NUMBER = 1;
    private int numberOfServings_ = 0;
    /**
     * <pre>
     * Number of servings available in a given menu item.
     * Optional.
     * </pre>
     *
     * <code>optional int32 number_of_servings = 1;</code>
     * @return Whether the numberOfServings field is set.
     */
    @java.lang.Override
    public boolean hasNumberOfServings() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * Number of servings available in a given menu item.
     * Optional.
     * </pre>
     *
     * <code>optional int32 number_of_servings = 1;</code>
     * @return The numberOfServings.
     */
    @java.lang.Override
    public int getNumberOfServings() {
      return numberOfServings_;
    }

    public static final int NUTRITION_INFORMATION_FIELD_NUMBER = 2;
    private food.menu.v1.FoodMenu.NutritionInformation nutritionInformation_;
    /**
     * <pre>
     * Describes all the nutritional information of the item, e.g. calories, fat
     * content.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
     * @return Whether the nutritionInformation field is set.
     */
    @java.lang.Override
    public boolean hasNutritionInformation() {
      return nutritionInformation_ != null;
    }
    /**
     * <pre>
     * Describes all the nutritional information of the item, e.g. calories, fat
     * content.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
     * @return The nutritionInformation.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.NutritionInformation getNutritionInformation() {
      return nutritionInformation_ == null ? food.menu.v1.FoodMenu.NutritionInformation.getDefaultInstance() : nutritionInformation_;
    }
    /**
     * <pre>
     * Describes all the nutritional information of the item, e.g. calories, fat
     * content.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.NutritionInformationOrBuilder getNutritionInformationOrBuilder() {
      return nutritionInformation_ == null ? food.menu.v1.FoodMenu.NutritionInformation.getDefaultInstance() : nutritionInformation_;
    }

    public static final int SUITABLE_DIETS_FIELD_NUMBER = 3;
    @SuppressWarnings("serial")
    private java.util.List<java.lang.Integer> suitableDiets_;
    private static final com.google.protobuf.Internal.ListAdapter.Converter<
        java.lang.Integer, food.menu.v1.FoodMenu.DietaryRestriction> suitableDiets_converter_ =
            new com.google.protobuf.Internal.ListAdapter.Converter<
                java.lang.Integer, food.menu.v1.FoodMenu.DietaryRestriction>() {
              public food.menu.v1.FoodMenu.DietaryRestriction convert(java.lang.Integer from) {
                food.menu.v1.FoodMenu.DietaryRestriction result = food.menu.v1.FoodMenu.DietaryRestriction.forNumber(from);
                return result == null ? food.menu.v1.FoodMenu.DietaryRestriction.UNRECOGNIZED : result;
              }
            };
    /**
     * <pre>
     * The dietary restrictions that this menu item complies with.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
     * @return A list containing the suitableDiets.
     */
    @java.lang.Override
    public java.util.List<food.menu.v1.FoodMenu.DietaryRestriction> getSuitableDietsList() {
      return new com.google.protobuf.Internal.ListAdapter<
          java.lang.Integer, food.menu.v1.FoodMenu.DietaryRestriction>(suitableDiets_, suitableDiets_converter_);
    }
    /**
     * <pre>
     * The dietary restrictions that this menu item complies with.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
     * @return The count of suitableDiets.
     */
    @java.lang.Override
    public int getSuitableDietsCount() {
      return suitableDiets_.size();
    }
    /**
     * <pre>
     * The dietary restrictions that this menu item complies with.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
     * @param index The index of the element to return.
     * @return The suitableDiets at the given index.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.DietaryRestriction getSuitableDiets(int index) {
      return suitableDiets_converter_.convert(suitableDiets_.get(index));
    }
    /**
     * <pre>
     * The dietary restrictions that this menu item complies with.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
     * @return A list containing the enum numeric values on the wire for suitableDiets.
     */
    @java.lang.Override
    public java.util.List<java.lang.Integer>
    getSuitableDietsValueList() {
      return suitableDiets_;
    }
    /**
     * <pre>
     * The dietary restrictions that this menu item complies with.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
     * @param index The index of the value to return.
     * @return The enum numeric value on the wire of suitableDiets at the given index.
     */
    @java.lang.Override
    public int getSuitableDietsValue(int index) {
      return suitableDiets_.get(index);
    }
    private int suitableDietsMemoizedSerializedSize;

    public static final int ADDITIVE_FIELD_NUMBER = 4;
    @SuppressWarnings("serial")
    private java.util.List<food.menu.v1.FoodMenu.Additive> additive_;
    /**
     * <pre>
     * Additives of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Additive additive = 4;</code>
     */
    @java.lang.Override
    public java.util.List<food.menu.v1.FoodMenu.Additive> getAdditiveList() {
      return additive_;
    }
    /**
     * <pre>
     * Additives of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Additive additive = 4;</code>
     */
    @java.lang.Override
    public java.util.List<? extends food.menu.v1.FoodMenu.AdditiveOrBuilder> 
        getAdditiveOrBuilderList() {
      return additive_;
    }
    /**
     * <pre>
     * Additives of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Additive additive = 4;</code>
     */
    @java.lang.Override
    public int getAdditiveCount() {
      return additive_.size();
    }
    /**
     * <pre>
     * Additives of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Additive additive = 4;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.Additive getAdditive(int index) {
      return additive_.get(index);
    }
    /**
     * <pre>
     * Additives of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Additive additive = 4;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.AdditiveOrBuilder getAdditiveOrBuilder(
        int index) {
      return additive_.get(index);
    }

    public static final int ALLERGEN_FIELD_NUMBER = 5;
    @SuppressWarnings("serial")
    private java.util.List<food.menu.v1.FoodMenu.Allergen> allergen_;
    /**
     * <pre>
     * Allergens of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
     */
    @java.lang.Override
    public java.util.List<food.menu.v1.FoodMenu.Allergen> getAllergenList() {
      return allergen_;
    }
    /**
     * <pre>
     * Allergens of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
     */
    @java.lang.Override
    public java.util.List<? extends food.menu.v1.FoodMenu.AllergenOrBuilder> 
        getAllergenOrBuilderList() {
      return allergen_;
    }
    /**
     * <pre>
     * Allergens of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
     */
    @java.lang.Override
    public int getAllergenCount() {
      return allergen_.size();
    }
    /**
     * <pre>
     * Allergens of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.Allergen getAllergen(int index) {
      return allergen_.get(index);
    }
    /**
     * <pre>
     * Allergens of this menu item.
     * Optional.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.AllergenOrBuilder getAllergenOrBuilder(
        int index) {
      return allergen_.get(index);
    }

    public static final int PACKAGING_DEPOSIT_INFO_FIELD_NUMBER = 6;
    private food.menu.v1.FoodMenu.DepositInfo packagingDepositInfo_;
    /**
     * <pre>
     * Packaging and recycling information of this menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
     * @return Whether the packagingDepositInfo field is set.
     */
    @java.lang.Override
    public boolean hasPackagingDepositInfo() {
      return packagingDepositInfo_ != null;
    }
    /**
     * <pre>
     * Packaging and recycling information of this menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
     * @return The packagingDepositInfo.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.DepositInfo getPackagingDepositInfo() {
      return packagingDepositInfo_ == null ? food.menu.v1.FoodMenu.DepositInfo.getDefaultInstance() : packagingDepositInfo_;
    }
    /**
     * <pre>
     * Packaging and recycling information of this menu item.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.DepositInfoOrBuilder getPackagingDepositInfoOrBuilder() {
      return packagingDepositInfo_ == null ? food.menu.v1.FoodMenu.DepositInfo.getDefaultInstance() : packagingDepositInfo_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(1, numberOfServings_);
      }
      if (nutritionInformation_ != null) {
        output.writeMessage(2, getNutritionInformation());
      }
      if (getSuitableDietsList().size() > 0) {
        output.writeUInt32NoTag(26);
        output.writeUInt32NoTag(suitableDietsMemoizedSerializedSize);
      }
      for (int i = 0; i < suitableDiets_.size(); i++) {
        output.writeEnumNoTag(suitableDiets_.get(i));
      }
      for (int i = 0; i < additive_.size(); i++) {
        output.writeMessage(4, additive_.get(i));
      }
      for (int i = 0; i < allergen_.size(); i++) {
        output.writeMessage(5, allergen_.get(i));
      }
      if (packagingDepositInfo_ != null) {
        output.writeMessage(6, getPackagingDepositInfo());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, numberOfServings_);
      }
      if (nutritionInformation_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getNutritionInformation());
      }
      {
        int dataSize = 0;
        for (int i = 0; i < suitableDiets_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeEnumSizeNoTag(suitableDiets_.get(i));
        }
        size += dataSize;
        if (!getSuitableDietsList().isEmpty()) {  size += 1;
          size += com.google.protobuf.CodedOutputStream
            .computeUInt32SizeNoTag(dataSize);
        }suitableDietsMemoizedSerializedSize = dataSize;
      }
      for (int i = 0; i < additive_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, additive_.get(i));
      }
      for (int i = 0; i < allergen_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(5, allergen_.get(i));
      }
      if (packagingDepositInfo_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(6, getPackagingDepositInfo());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.MenuItemAttributes)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.MenuItemAttributes other = (food.menu.v1.FoodMenu.MenuItemAttributes) obj;

      if (hasNumberOfServings() != other.hasNumberOfServings()) return false;
      if (hasNumberOfServings()) {
        if (getNumberOfServings()
            != other.getNumberOfServings()) return false;
      }
      if (hasNutritionInformation() != other.hasNutritionInformation()) return false;
      if (hasNutritionInformation()) {
        if (!getNutritionInformation()
            .equals(other.getNutritionInformation())) return false;
      }
      if (!suitableDiets_.equals(other.suitableDiets_)) return false;
      if (!getAdditiveList()
          .equals(other.getAdditiveList())) return false;
      if (!getAllergenList()
          .equals(other.getAllergenList())) return false;
      if (hasPackagingDepositInfo() != other.hasPackagingDepositInfo()) return false;
      if (hasPackagingDepositInfo()) {
        if (!getPackagingDepositInfo()
            .equals(other.getPackagingDepositInfo())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasNumberOfServings()) {
        hash = (37 * hash) + NUMBER_OF_SERVINGS_FIELD_NUMBER;
        hash = (53 * hash) + getNumberOfServings();
      }
      if (hasNutritionInformation()) {
        hash = (37 * hash) + NUTRITION_INFORMATION_FIELD_NUMBER;
        hash = (53 * hash) + getNutritionInformation().hashCode();
      }
      if (getSuitableDietsCount() > 0) {
        hash = (37 * hash) + SUITABLE_DIETS_FIELD_NUMBER;
        hash = (53 * hash) + suitableDiets_.hashCode();
      }
      if (getAdditiveCount() > 0) {
        hash = (37 * hash) + ADDITIVE_FIELD_NUMBER;
        hash = (53 * hash) + getAdditiveList().hashCode();
      }
      if (getAllergenCount() > 0) {
        hash = (37 * hash) + ALLERGEN_FIELD_NUMBER;
        hash = (53 * hash) + getAllergenList().hashCode();
      }
      if (hasPackagingDepositInfo()) {
        hash = (37 * hash) + PACKAGING_DEPOSIT_INFO_FIELD_NUMBER;
        hash = (53 * hash) + getPackagingDepositInfo().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.MenuItemAttributes parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuItemAttributes parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemAttributes parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuItemAttributes parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemAttributes parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuItemAttributes parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemAttributes parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuItemAttributes parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemAttributes parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuItemAttributes parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemAttributes parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuItemAttributes parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.MenuItemAttributes prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Describes attributes about a particular menu item or option.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.MenuItemAttributes}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.MenuItemAttributes)
        food.menu.v1.FoodMenu.MenuItemAttributesOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemAttributes_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemAttributes_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.MenuItemAttributes.class, food.menu.v1.FoodMenu.MenuItemAttributes.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.MenuItemAttributes.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        numberOfServings_ = 0;
        nutritionInformation_ = null;
        if (nutritionInformationBuilder_ != null) {
          nutritionInformationBuilder_.dispose();
          nutritionInformationBuilder_ = null;
        }
        suitableDiets_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000004);
        if (additiveBuilder_ == null) {
          additive_ = java.util.Collections.emptyList();
        } else {
          additive_ = null;
          additiveBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        if (allergenBuilder_ == null) {
          allergen_ = java.util.Collections.emptyList();
        } else {
          allergen_ = null;
          allergenBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        packagingDepositInfo_ = null;
        if (packagingDepositInfoBuilder_ != null) {
          packagingDepositInfoBuilder_.dispose();
          packagingDepositInfoBuilder_ = null;
        }
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemAttributes_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemAttributes getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.MenuItemAttributes.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemAttributes build() {
        food.menu.v1.FoodMenu.MenuItemAttributes result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemAttributes buildPartial() {
        food.menu.v1.FoodMenu.MenuItemAttributes result = new food.menu.v1.FoodMenu.MenuItemAttributes(this);
        buildPartialRepeatedFields(result);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartialRepeatedFields(food.menu.v1.FoodMenu.MenuItemAttributes result) {
        if (((bitField0_ & 0x00000004) != 0)) {
          suitableDiets_ = java.util.Collections.unmodifiableList(suitableDiets_);
          bitField0_ = (bitField0_ & ~0x00000004);
        }
        result.suitableDiets_ = suitableDiets_;
        if (additiveBuilder_ == null) {
          if (((bitField0_ & 0x00000008) != 0)) {
            additive_ = java.util.Collections.unmodifiableList(additive_);
            bitField0_ = (bitField0_ & ~0x00000008);
          }
          result.additive_ = additive_;
        } else {
          result.additive_ = additiveBuilder_.build();
        }
        if (allergenBuilder_ == null) {
          if (((bitField0_ & 0x00000010) != 0)) {
            allergen_ = java.util.Collections.unmodifiableList(allergen_);
            bitField0_ = (bitField0_ & ~0x00000010);
          }
          result.allergen_ = allergen_;
        } else {
          result.allergen_ = allergenBuilder_.build();
        }
      }

      private void buildPartial0(food.menu.v1.FoodMenu.MenuItemAttributes result) {
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.numberOfServings_ = numberOfServings_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.nutritionInformation_ = nutritionInformationBuilder_ == null
              ? nutritionInformation_
              : nutritionInformationBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          result.packagingDepositInfo_ = packagingDepositInfoBuilder_ == null
              ? packagingDepositInfo_
              : packagingDepositInfoBuilder_.build();
        }
        result.bitField0_ |= to_bitField0_;
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.MenuItemAttributes) {
          return mergeFrom((food.menu.v1.FoodMenu.MenuItemAttributes)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.MenuItemAttributes other) {
        if (other == food.menu.v1.FoodMenu.MenuItemAttributes.getDefaultInstance()) return this;
        if (other.hasNumberOfServings()) {
          setNumberOfServings(other.getNumberOfServings());
        }
        if (other.hasNutritionInformation()) {
          mergeNutritionInformation(other.getNutritionInformation());
        }
        if (!other.suitableDiets_.isEmpty()) {
          if (suitableDiets_.isEmpty()) {
            suitableDiets_ = other.suitableDiets_;
            bitField0_ = (bitField0_ & ~0x00000004);
          } else {
            ensureSuitableDietsIsMutable();
            suitableDiets_.addAll(other.suitableDiets_);
          }
          onChanged();
        }
        if (additiveBuilder_ == null) {
          if (!other.additive_.isEmpty()) {
            if (additive_.isEmpty()) {
              additive_ = other.additive_;
              bitField0_ = (bitField0_ & ~0x00000008);
            } else {
              ensureAdditiveIsMutable();
              additive_.addAll(other.additive_);
            }
            onChanged();
          }
        } else {
          if (!other.additive_.isEmpty()) {
            if (additiveBuilder_.isEmpty()) {
              additiveBuilder_.dispose();
              additiveBuilder_ = null;
              additive_ = other.additive_;
              bitField0_ = (bitField0_ & ~0x00000008);
              additiveBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getAdditiveFieldBuilder() : null;
            } else {
              additiveBuilder_.addAllMessages(other.additive_);
            }
          }
        }
        if (allergenBuilder_ == null) {
          if (!other.allergen_.isEmpty()) {
            if (allergen_.isEmpty()) {
              allergen_ = other.allergen_;
              bitField0_ = (bitField0_ & ~0x00000010);
            } else {
              ensureAllergenIsMutable();
              allergen_.addAll(other.allergen_);
            }
            onChanged();
          }
        } else {
          if (!other.allergen_.isEmpty()) {
            if (allergenBuilder_.isEmpty()) {
              allergenBuilder_.dispose();
              allergenBuilder_ = null;
              allergen_ = other.allergen_;
              bitField0_ = (bitField0_ & ~0x00000010);
              allergenBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getAllergenFieldBuilder() : null;
            } else {
              allergenBuilder_.addAllMessages(other.allergen_);
            }
          }
        }
        if (other.hasPackagingDepositInfo()) {
          mergePackagingDepositInfo(other.getPackagingDepositInfo());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                numberOfServings_ = input.readInt32();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 18: {
                input.readMessage(
                    getNutritionInformationFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 24: {
                int tmpRaw = input.readEnum();
                ensureSuitableDietsIsMutable();
                suitableDiets_.add(tmpRaw);
                break;
              } // case 24
              case 26: {
                int length = input.readRawVarint32();
                int oldLimit = input.pushLimit(length);
                while(input.getBytesUntilLimit() > 0) {
                  int tmpRaw = input.readEnum();
                  ensureSuitableDietsIsMutable();
                  suitableDiets_.add(tmpRaw);
                }
                input.popLimit(oldLimit);
                break;
              } // case 26
              case 34: {
                food.menu.v1.FoodMenu.Additive m =
                    input.readMessage(
                        food.menu.v1.FoodMenu.Additive.parser(),
                        extensionRegistry);
                if (additiveBuilder_ == null) {
                  ensureAdditiveIsMutable();
                  additive_.add(m);
                } else {
                  additiveBuilder_.addMessage(m);
                }
                break;
              } // case 34
              case 42: {
                food.menu.v1.FoodMenu.Allergen m =
                    input.readMessage(
                        food.menu.v1.FoodMenu.Allergen.parser(),
                        extensionRegistry);
                if (allergenBuilder_ == null) {
                  ensureAllergenIsMutable();
                  allergen_.add(m);
                } else {
                  allergenBuilder_.addMessage(m);
                }
                break;
              } // case 42
              case 50: {
                input.readMessage(
                    getPackagingDepositInfoFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000020;
                break;
              } // case 50
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int numberOfServings_ ;
      /**
       * <pre>
       * Number of servings available in a given menu item.
       * Optional.
       * </pre>
       *
       * <code>optional int32 number_of_servings = 1;</code>
       * @return Whether the numberOfServings field is set.
       */
      @java.lang.Override
      public boolean hasNumberOfServings() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * Number of servings available in a given menu item.
       * Optional.
       * </pre>
       *
       * <code>optional int32 number_of_servings = 1;</code>
       * @return The numberOfServings.
       */
      @java.lang.Override
      public int getNumberOfServings() {
        return numberOfServings_;
      }
      /**
       * <pre>
       * Number of servings available in a given menu item.
       * Optional.
       * </pre>
       *
       * <code>optional int32 number_of_servings = 1;</code>
       * @param value The numberOfServings to set.
       * @return This builder for chaining.
       */
      public Builder setNumberOfServings(int value) {

        numberOfServings_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Number of servings available in a given menu item.
       * Optional.
       * </pre>
       *
       * <code>optional int32 number_of_servings = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearNumberOfServings() {
        bitField0_ = (bitField0_ & ~0x00000001);
        numberOfServings_ = 0;
        onChanged();
        return this;
      }

      private food.menu.v1.FoodMenu.NutritionInformation nutritionInformation_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.NutritionInformation, food.menu.v1.FoodMenu.NutritionInformation.Builder, food.menu.v1.FoodMenu.NutritionInformationOrBuilder> nutritionInformationBuilder_;
      /**
       * <pre>
       * Describes all the nutritional information of the item, e.g. calories, fat
       * content.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
       * @return Whether the nutritionInformation field is set.
       */
      public boolean hasNutritionInformation() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * Describes all the nutritional information of the item, e.g. calories, fat
       * content.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
       * @return The nutritionInformation.
       */
      public food.menu.v1.FoodMenu.NutritionInformation getNutritionInformation() {
        if (nutritionInformationBuilder_ == null) {
          return nutritionInformation_ == null ? food.menu.v1.FoodMenu.NutritionInformation.getDefaultInstance() : nutritionInformation_;
        } else {
          return nutritionInformationBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Describes all the nutritional information of the item, e.g. calories, fat
       * content.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
       */
      public Builder setNutritionInformation(food.menu.v1.FoodMenu.NutritionInformation value) {
        if (nutritionInformationBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          nutritionInformation_ = value;
        } else {
          nutritionInformationBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Describes all the nutritional information of the item, e.g. calories, fat
       * content.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
       */
      public Builder setNutritionInformation(
          food.menu.v1.FoodMenu.NutritionInformation.Builder builderForValue) {
        if (nutritionInformationBuilder_ == null) {
          nutritionInformation_ = builderForValue.build();
        } else {
          nutritionInformationBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Describes all the nutritional information of the item, e.g. calories, fat
       * content.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
       */
      public Builder mergeNutritionInformation(food.menu.v1.FoodMenu.NutritionInformation value) {
        if (nutritionInformationBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
            nutritionInformation_ != null &&
            nutritionInformation_ != food.menu.v1.FoodMenu.NutritionInformation.getDefaultInstance()) {
            getNutritionInformationBuilder().mergeFrom(value);
          } else {
            nutritionInformation_ = value;
          }
        } else {
          nutritionInformationBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Describes all the nutritional information of the item, e.g. calories, fat
       * content.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
       */
      public Builder clearNutritionInformation() {
        bitField0_ = (bitField0_ & ~0x00000002);
        nutritionInformation_ = null;
        if (nutritionInformationBuilder_ != null) {
          nutritionInformationBuilder_.dispose();
          nutritionInformationBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Describes all the nutritional information of the item, e.g. calories, fat
       * content.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
       */
      public food.menu.v1.FoodMenu.NutritionInformation.Builder getNutritionInformationBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getNutritionInformationFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Describes all the nutritional information of the item, e.g. calories, fat
       * content.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
       */
      public food.menu.v1.FoodMenu.NutritionInformationOrBuilder getNutritionInformationOrBuilder() {
        if (nutritionInformationBuilder_ != null) {
          return nutritionInformationBuilder_.getMessageOrBuilder();
        } else {
          return nutritionInformation_ == null ?
              food.menu.v1.FoodMenu.NutritionInformation.getDefaultInstance() : nutritionInformation_;
        }
      }
      /**
       * <pre>
       * Describes all the nutritional information of the item, e.g. calories, fat
       * content.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation nutrition_information = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.NutritionInformation, food.menu.v1.FoodMenu.NutritionInformation.Builder, food.menu.v1.FoodMenu.NutritionInformationOrBuilder> 
          getNutritionInformationFieldBuilder() {
        if (nutritionInformationBuilder_ == null) {
          nutritionInformationBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.NutritionInformation, food.menu.v1.FoodMenu.NutritionInformation.Builder, food.menu.v1.FoodMenu.NutritionInformationOrBuilder>(
                  getNutritionInformation(),
                  getParentForChildren(),
                  isClean());
          nutritionInformation_ = null;
        }
        return nutritionInformationBuilder_;
      }

      private java.util.List<java.lang.Integer> suitableDiets_ =
        java.util.Collections.emptyList();
      private void ensureSuitableDietsIsMutable() {
        if (!((bitField0_ & 0x00000004) != 0)) {
          suitableDiets_ = new java.util.ArrayList<java.lang.Integer>(suitableDiets_);
          bitField0_ |= 0x00000004;
        }
      }
      /**
       * <pre>
       * The dietary restrictions that this menu item complies with.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
       * @return A list containing the suitableDiets.
       */
      public java.util.List<food.menu.v1.FoodMenu.DietaryRestriction> getSuitableDietsList() {
        return new com.google.protobuf.Internal.ListAdapter<
            java.lang.Integer, food.menu.v1.FoodMenu.DietaryRestriction>(suitableDiets_, suitableDiets_converter_);
      }
      /**
       * <pre>
       * The dietary restrictions that this menu item complies with.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
       * @return The count of suitableDiets.
       */
      public int getSuitableDietsCount() {
        return suitableDiets_.size();
      }
      /**
       * <pre>
       * The dietary restrictions that this menu item complies with.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
       * @param index The index of the element to return.
       * @return The suitableDiets at the given index.
       */
      public food.menu.v1.FoodMenu.DietaryRestriction getSuitableDiets(int index) {
        return suitableDiets_converter_.convert(suitableDiets_.get(index));
      }
      /**
       * <pre>
       * The dietary restrictions that this menu item complies with.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
       * @param index The index to set the value at.
       * @param value The suitableDiets to set.
       * @return This builder for chaining.
       */
      public Builder setSuitableDiets(
          int index, food.menu.v1.FoodMenu.DietaryRestriction value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureSuitableDietsIsMutable();
        suitableDiets_.set(index, value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The dietary restrictions that this menu item complies with.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
       * @param value The suitableDiets to add.
       * @return This builder for chaining.
       */
      public Builder addSuitableDiets(food.menu.v1.FoodMenu.DietaryRestriction value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureSuitableDietsIsMutable();
        suitableDiets_.add(value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The dietary restrictions that this menu item complies with.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
       * @param values The suitableDiets to add.
       * @return This builder for chaining.
       */
      public Builder addAllSuitableDiets(
          java.lang.Iterable<? extends food.menu.v1.FoodMenu.DietaryRestriction> values) {
        ensureSuitableDietsIsMutable();
        for (food.menu.v1.FoodMenu.DietaryRestriction value : values) {
          suitableDiets_.add(value.getNumber());
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The dietary restrictions that this menu item complies with.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearSuitableDiets() {
        suitableDiets_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000004);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The dietary restrictions that this menu item complies with.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
       * @return A list containing the enum numeric values on the wire for suitableDiets.
       */
      public java.util.List<java.lang.Integer>
      getSuitableDietsValueList() {
        return java.util.Collections.unmodifiableList(suitableDiets_);
      }
      /**
       * <pre>
       * The dietary restrictions that this menu item complies with.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
       * @param index The index of the value to return.
       * @return The enum numeric value on the wire of suitableDiets at the given index.
       */
      public int getSuitableDietsValue(int index) {
        return suitableDiets_.get(index);
      }
      /**
       * <pre>
       * The dietary restrictions that this menu item complies with.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
       * @param index The index to set the value at.
       * @param value The enum numeric value on the wire for suitableDiets to set.
       * @return This builder for chaining.
       */
      public Builder setSuitableDietsValue(
          int index, int value) {
        ensureSuitableDietsIsMutable();
        suitableDiets_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The dietary restrictions that this menu item complies with.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
       * @param value The enum numeric value on the wire for suitableDiets to add.
       * @return This builder for chaining.
       */
      public Builder addSuitableDietsValue(int value) {
        ensureSuitableDietsIsMutable();
        suitableDiets_.add(value);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The dietary restrictions that this menu item complies with.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.DietaryRestriction suitable_diets = 3;</code>
       * @param values The enum numeric values on the wire for suitableDiets to add.
       * @return This builder for chaining.
       */
      public Builder addAllSuitableDietsValue(
          java.lang.Iterable<java.lang.Integer> values) {
        ensureSuitableDietsIsMutable();
        for (int value : values) {
          suitableDiets_.add(value);
        }
        onChanged();
        return this;
      }

      private java.util.List<food.menu.v1.FoodMenu.Additive> additive_ =
        java.util.Collections.emptyList();
      private void ensureAdditiveIsMutable() {
        if (!((bitField0_ & 0x00000008) != 0)) {
          additive_ = new java.util.ArrayList<food.menu.v1.FoodMenu.Additive>(additive_);
          bitField0_ |= 0x00000008;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          food.menu.v1.FoodMenu.Additive, food.menu.v1.FoodMenu.Additive.Builder, food.menu.v1.FoodMenu.AdditiveOrBuilder> additiveBuilder_;

      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public java.util.List<food.menu.v1.FoodMenu.Additive> getAdditiveList() {
        if (additiveBuilder_ == null) {
          return java.util.Collections.unmodifiableList(additive_);
        } else {
          return additiveBuilder_.getMessageList();
        }
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public int getAdditiveCount() {
        if (additiveBuilder_ == null) {
          return additive_.size();
        } else {
          return additiveBuilder_.getCount();
        }
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public food.menu.v1.FoodMenu.Additive getAdditive(int index) {
        if (additiveBuilder_ == null) {
          return additive_.get(index);
        } else {
          return additiveBuilder_.getMessage(index);
        }
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public Builder setAdditive(
          int index, food.menu.v1.FoodMenu.Additive value) {
        if (additiveBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureAdditiveIsMutable();
          additive_.set(index, value);
          onChanged();
        } else {
          additiveBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public Builder setAdditive(
          int index, food.menu.v1.FoodMenu.Additive.Builder builderForValue) {
        if (additiveBuilder_ == null) {
          ensureAdditiveIsMutable();
          additive_.set(index, builderForValue.build());
          onChanged();
        } else {
          additiveBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public Builder addAdditive(food.menu.v1.FoodMenu.Additive value) {
        if (additiveBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureAdditiveIsMutable();
          additive_.add(value);
          onChanged();
        } else {
          additiveBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public Builder addAdditive(
          int index, food.menu.v1.FoodMenu.Additive value) {
        if (additiveBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureAdditiveIsMutable();
          additive_.add(index, value);
          onChanged();
        } else {
          additiveBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public Builder addAdditive(
          food.menu.v1.FoodMenu.Additive.Builder builderForValue) {
        if (additiveBuilder_ == null) {
          ensureAdditiveIsMutable();
          additive_.add(builderForValue.build());
          onChanged();
        } else {
          additiveBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public Builder addAdditive(
          int index, food.menu.v1.FoodMenu.Additive.Builder builderForValue) {
        if (additiveBuilder_ == null) {
          ensureAdditiveIsMutable();
          additive_.add(index, builderForValue.build());
          onChanged();
        } else {
          additiveBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public Builder addAllAdditive(
          java.lang.Iterable<? extends food.menu.v1.FoodMenu.Additive> values) {
        if (additiveBuilder_ == null) {
          ensureAdditiveIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, additive_);
          onChanged();
        } else {
          additiveBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public Builder clearAdditive() {
        if (additiveBuilder_ == null) {
          additive_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000008);
          onChanged();
        } else {
          additiveBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public Builder removeAdditive(int index) {
        if (additiveBuilder_ == null) {
          ensureAdditiveIsMutable();
          additive_.remove(index);
          onChanged();
        } else {
          additiveBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public food.menu.v1.FoodMenu.Additive.Builder getAdditiveBuilder(
          int index) {
        return getAdditiveFieldBuilder().getBuilder(index);
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public food.menu.v1.FoodMenu.AdditiveOrBuilder getAdditiveOrBuilder(
          int index) {
        if (additiveBuilder_ == null) {
          return additive_.get(index);  } else {
          return additiveBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public java.util.List<? extends food.menu.v1.FoodMenu.AdditiveOrBuilder> 
           getAdditiveOrBuilderList() {
        if (additiveBuilder_ != null) {
          return additiveBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(additive_);
        }
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public food.menu.v1.FoodMenu.Additive.Builder addAdditiveBuilder() {
        return getAdditiveFieldBuilder().addBuilder(
            food.menu.v1.FoodMenu.Additive.getDefaultInstance());
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public food.menu.v1.FoodMenu.Additive.Builder addAdditiveBuilder(
          int index) {
        return getAdditiveFieldBuilder().addBuilder(
            index, food.menu.v1.FoodMenu.Additive.getDefaultInstance());
      }
      /**
       * <pre>
       * Additives of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Additive additive = 4;</code>
       */
      public java.util.List<food.menu.v1.FoodMenu.Additive.Builder> 
           getAdditiveBuilderList() {
        return getAdditiveFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          food.menu.v1.FoodMenu.Additive, food.menu.v1.FoodMenu.Additive.Builder, food.menu.v1.FoodMenu.AdditiveOrBuilder> 
          getAdditiveFieldBuilder() {
        if (additiveBuilder_ == null) {
          additiveBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              food.menu.v1.FoodMenu.Additive, food.menu.v1.FoodMenu.Additive.Builder, food.menu.v1.FoodMenu.AdditiveOrBuilder>(
                  additive_,
                  ((bitField0_ & 0x00000008) != 0),
                  getParentForChildren(),
                  isClean());
          additive_ = null;
        }
        return additiveBuilder_;
      }

      private java.util.List<food.menu.v1.FoodMenu.Allergen> allergen_ =
        java.util.Collections.emptyList();
      private void ensureAllergenIsMutable() {
        if (!((bitField0_ & 0x00000010) != 0)) {
          allergen_ = new java.util.ArrayList<food.menu.v1.FoodMenu.Allergen>(allergen_);
          bitField0_ |= 0x00000010;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          food.menu.v1.FoodMenu.Allergen, food.menu.v1.FoodMenu.Allergen.Builder, food.menu.v1.FoodMenu.AllergenOrBuilder> allergenBuilder_;

      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public java.util.List<food.menu.v1.FoodMenu.Allergen> getAllergenList() {
        if (allergenBuilder_ == null) {
          return java.util.Collections.unmodifiableList(allergen_);
        } else {
          return allergenBuilder_.getMessageList();
        }
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public int getAllergenCount() {
        if (allergenBuilder_ == null) {
          return allergen_.size();
        } else {
          return allergenBuilder_.getCount();
        }
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public food.menu.v1.FoodMenu.Allergen getAllergen(int index) {
        if (allergenBuilder_ == null) {
          return allergen_.get(index);
        } else {
          return allergenBuilder_.getMessage(index);
        }
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public Builder setAllergen(
          int index, food.menu.v1.FoodMenu.Allergen value) {
        if (allergenBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureAllergenIsMutable();
          allergen_.set(index, value);
          onChanged();
        } else {
          allergenBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public Builder setAllergen(
          int index, food.menu.v1.FoodMenu.Allergen.Builder builderForValue) {
        if (allergenBuilder_ == null) {
          ensureAllergenIsMutable();
          allergen_.set(index, builderForValue.build());
          onChanged();
        } else {
          allergenBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public Builder addAllergen(food.menu.v1.FoodMenu.Allergen value) {
        if (allergenBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureAllergenIsMutable();
          allergen_.add(value);
          onChanged();
        } else {
          allergenBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public Builder addAllergen(
          int index, food.menu.v1.FoodMenu.Allergen value) {
        if (allergenBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureAllergenIsMutable();
          allergen_.add(index, value);
          onChanged();
        } else {
          allergenBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public Builder addAllergen(
          food.menu.v1.FoodMenu.Allergen.Builder builderForValue) {
        if (allergenBuilder_ == null) {
          ensureAllergenIsMutable();
          allergen_.add(builderForValue.build());
          onChanged();
        } else {
          allergenBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public Builder addAllergen(
          int index, food.menu.v1.FoodMenu.Allergen.Builder builderForValue) {
        if (allergenBuilder_ == null) {
          ensureAllergenIsMutable();
          allergen_.add(index, builderForValue.build());
          onChanged();
        } else {
          allergenBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public Builder addAllAllergen(
          java.lang.Iterable<? extends food.menu.v1.FoodMenu.Allergen> values) {
        if (allergenBuilder_ == null) {
          ensureAllergenIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, allergen_);
          onChanged();
        } else {
          allergenBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public Builder clearAllergen() {
        if (allergenBuilder_ == null) {
          allergen_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000010);
          onChanged();
        } else {
          allergenBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public Builder removeAllergen(int index) {
        if (allergenBuilder_ == null) {
          ensureAllergenIsMutable();
          allergen_.remove(index);
          onChanged();
        } else {
          allergenBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public food.menu.v1.FoodMenu.Allergen.Builder getAllergenBuilder(
          int index) {
        return getAllergenFieldBuilder().getBuilder(index);
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public food.menu.v1.FoodMenu.AllergenOrBuilder getAllergenOrBuilder(
          int index) {
        if (allergenBuilder_ == null) {
          return allergen_.get(index);  } else {
          return allergenBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public java.util.List<? extends food.menu.v1.FoodMenu.AllergenOrBuilder> 
           getAllergenOrBuilderList() {
        if (allergenBuilder_ != null) {
          return allergenBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(allergen_);
        }
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public food.menu.v1.FoodMenu.Allergen.Builder addAllergenBuilder() {
        return getAllergenFieldBuilder().addBuilder(
            food.menu.v1.FoodMenu.Allergen.getDefaultInstance());
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public food.menu.v1.FoodMenu.Allergen.Builder addAllergenBuilder(
          int index) {
        return getAllergenFieldBuilder().addBuilder(
            index, food.menu.v1.FoodMenu.Allergen.getDefaultInstance());
      }
      /**
       * <pre>
       * Allergens of this menu item.
       * Optional.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Allergen allergen = 5;</code>
       */
      public java.util.List<food.menu.v1.FoodMenu.Allergen.Builder> 
           getAllergenBuilderList() {
        return getAllergenFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          food.menu.v1.FoodMenu.Allergen, food.menu.v1.FoodMenu.Allergen.Builder, food.menu.v1.FoodMenu.AllergenOrBuilder> 
          getAllergenFieldBuilder() {
        if (allergenBuilder_ == null) {
          allergenBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              food.menu.v1.FoodMenu.Allergen, food.menu.v1.FoodMenu.Allergen.Builder, food.menu.v1.FoodMenu.AllergenOrBuilder>(
                  allergen_,
                  ((bitField0_ & 0x00000010) != 0),
                  getParentForChildren(),
                  isClean());
          allergen_ = null;
        }
        return allergenBuilder_;
      }

      private food.menu.v1.FoodMenu.DepositInfo packagingDepositInfo_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.DepositInfo, food.menu.v1.FoodMenu.DepositInfo.Builder, food.menu.v1.FoodMenu.DepositInfoOrBuilder> packagingDepositInfoBuilder_;
      /**
       * <pre>
       * Packaging and recycling information of this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
       * @return Whether the packagingDepositInfo field is set.
       */
      public boolean hasPackagingDepositInfo() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <pre>
       * Packaging and recycling information of this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
       * @return The packagingDepositInfo.
       */
      public food.menu.v1.FoodMenu.DepositInfo getPackagingDepositInfo() {
        if (packagingDepositInfoBuilder_ == null) {
          return packagingDepositInfo_ == null ? food.menu.v1.FoodMenu.DepositInfo.getDefaultInstance() : packagingDepositInfo_;
        } else {
          return packagingDepositInfoBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Packaging and recycling information of this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
       */
      public Builder setPackagingDepositInfo(food.menu.v1.FoodMenu.DepositInfo value) {
        if (packagingDepositInfoBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          packagingDepositInfo_ = value;
        } else {
          packagingDepositInfoBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000020;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Packaging and recycling information of this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
       */
      public Builder setPackagingDepositInfo(
          food.menu.v1.FoodMenu.DepositInfo.Builder builderForValue) {
        if (packagingDepositInfoBuilder_ == null) {
          packagingDepositInfo_ = builderForValue.build();
        } else {
          packagingDepositInfoBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000020;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Packaging and recycling information of this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
       */
      public Builder mergePackagingDepositInfo(food.menu.v1.FoodMenu.DepositInfo value) {
        if (packagingDepositInfoBuilder_ == null) {
          if (((bitField0_ & 0x00000020) != 0) &&
            packagingDepositInfo_ != null &&
            packagingDepositInfo_ != food.menu.v1.FoodMenu.DepositInfo.getDefaultInstance()) {
            getPackagingDepositInfoBuilder().mergeFrom(value);
          } else {
            packagingDepositInfo_ = value;
          }
        } else {
          packagingDepositInfoBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000020;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Packaging and recycling information of this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
       */
      public Builder clearPackagingDepositInfo() {
        bitField0_ = (bitField0_ & ~0x00000020);
        packagingDepositInfo_ = null;
        if (packagingDepositInfoBuilder_ != null) {
          packagingDepositInfoBuilder_.dispose();
          packagingDepositInfoBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Packaging and recycling information of this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
       */
      public food.menu.v1.FoodMenu.DepositInfo.Builder getPackagingDepositInfoBuilder() {
        bitField0_ |= 0x00000020;
        onChanged();
        return getPackagingDepositInfoFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Packaging and recycling information of this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
       */
      public food.menu.v1.FoodMenu.DepositInfoOrBuilder getPackagingDepositInfoOrBuilder() {
        if (packagingDepositInfoBuilder_ != null) {
          return packagingDepositInfoBuilder_.getMessageOrBuilder();
        } else {
          return packagingDepositInfo_ == null ?
              food.menu.v1.FoodMenu.DepositInfo.getDefaultInstance() : packagingDepositInfo_;
        }
      }
      /**
       * <pre>
       * Packaging and recycling information of this menu item.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.DepositInfo packaging_deposit_info = 6;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.DepositInfo, food.menu.v1.FoodMenu.DepositInfo.Builder, food.menu.v1.FoodMenu.DepositInfoOrBuilder> 
          getPackagingDepositInfoFieldBuilder() {
        if (packagingDepositInfoBuilder_ == null) {
          packagingDepositInfoBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.DepositInfo, food.menu.v1.FoodMenu.DepositInfo.Builder, food.menu.v1.FoodMenu.DepositInfoOrBuilder>(
                  getPackagingDepositInfo(),
                  getParentForChildren(),
                  isClean());
          packagingDepositInfo_ = null;
        }
        return packagingDepositInfoBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.MenuItemAttributes)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.MenuItemAttributes)
    private static final food.menu.v1.FoodMenu.MenuItemAttributes DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.MenuItemAttributes();
    }

    public static food.menu.v1.FoodMenu.MenuItemAttributes getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<MenuItemAttributes>
        PARSER = new com.google.protobuf.AbstractParser<MenuItemAttributes>() {
      @java.lang.Override
      public MenuItemAttributes parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<MenuItemAttributes> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<MenuItemAttributes> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItemAttributes getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface OfferSetOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.OfferSet)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * List of possible offers.
     * Required.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Offer offers = 1;</code>
     */
    java.util.List<food.menu.v1.FoodMenu.Offer> 
        getOffersList();
    /**
     * <pre>
     * List of possible offers.
     * Required.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Offer offers = 1;</code>
     */
    food.menu.v1.FoodMenu.Offer getOffers(int index);
    /**
     * <pre>
     * List of possible offers.
     * Required.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Offer offers = 1;</code>
     */
    int getOffersCount();
    /**
     * <pre>
     * List of possible offers.
     * Required.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Offer offers = 1;</code>
     */
    java.util.List<? extends food.menu.v1.FoodMenu.OfferOrBuilder> 
        getOffersOrBuilderList();
    /**
     * <pre>
     * List of possible offers.
     * Required.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Offer offers = 1;</code>
     */
    food.menu.v1.FoodMenu.OfferOrBuilder getOffersOrBuilder(
        int index);
  }
  /**
   * <pre>
   * Container for a list of offers available on a menu item / option.
   * Only one offer should be applicable/valid at one particular time.
   * For example, a drink can have 2 offers where one is applicable in the morning
   * while the other is applicable in the evening during happy hours.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.OfferSet}
   */
  public static final class OfferSet extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.OfferSet)
      OfferSetOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use OfferSet.newBuilder() to construct.
    private OfferSet(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private OfferSet() {
      offers_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new OfferSet();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_OfferSet_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_OfferSet_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.OfferSet.class, food.menu.v1.FoodMenu.OfferSet.Builder.class);
    }

    public static final int OFFERS_FIELD_NUMBER = 1;
    @SuppressWarnings("serial")
    private java.util.List<food.menu.v1.FoodMenu.Offer> offers_;
    /**
     * <pre>
     * List of possible offers.
     * Required.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Offer offers = 1;</code>
     */
    @java.lang.Override
    public java.util.List<food.menu.v1.FoodMenu.Offer> getOffersList() {
      return offers_;
    }
    /**
     * <pre>
     * List of possible offers.
     * Required.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Offer offers = 1;</code>
     */
    @java.lang.Override
    public java.util.List<? extends food.menu.v1.FoodMenu.OfferOrBuilder> 
        getOffersOrBuilderList() {
      return offers_;
    }
    /**
     * <pre>
     * List of possible offers.
     * Required.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Offer offers = 1;</code>
     */
    @java.lang.Override
    public int getOffersCount() {
      return offers_.size();
    }
    /**
     * <pre>
     * List of possible offers.
     * Required.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Offer offers = 1;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.Offer getOffers(int index) {
      return offers_.get(index);
    }
    /**
     * <pre>
     * List of possible offers.
     * Required.
     * </pre>
     *
     * <code>repeated .food.menu.v1.Offer offers = 1;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.OfferOrBuilder getOffersOrBuilder(
        int index) {
      return offers_.get(index);
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      for (int i = 0; i < offers_.size(); i++) {
        output.writeMessage(1, offers_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < offers_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, offers_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.OfferSet)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.OfferSet other = (food.menu.v1.FoodMenu.OfferSet) obj;

      if (!getOffersList()
          .equals(other.getOffersList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (getOffersCount() > 0) {
        hash = (37 * hash) + OFFERS_FIELD_NUMBER;
        hash = (53 * hash) + getOffersList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.OfferSet parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.OfferSet parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.OfferSet parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.OfferSet parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.OfferSet parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.OfferSet parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.OfferSet parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.OfferSet parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.OfferSet parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.OfferSet parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.OfferSet parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.OfferSet parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.OfferSet prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Container for a list of offers available on a menu item / option.
     * Only one offer should be applicable/valid at one particular time.
     * For example, a drink can have 2 offers where one is applicable in the morning
     * while the other is applicable in the evening during happy hours.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.OfferSet}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.OfferSet)
        food.menu.v1.FoodMenu.OfferSetOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_OfferSet_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_OfferSet_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.OfferSet.class, food.menu.v1.FoodMenu.OfferSet.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.OfferSet.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        if (offersBuilder_ == null) {
          offers_ = java.util.Collections.emptyList();
        } else {
          offers_ = null;
          offersBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_OfferSet_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.OfferSet getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.OfferSet.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.OfferSet build() {
        food.menu.v1.FoodMenu.OfferSet result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.OfferSet buildPartial() {
        food.menu.v1.FoodMenu.OfferSet result = new food.menu.v1.FoodMenu.OfferSet(this);
        buildPartialRepeatedFields(result);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartialRepeatedFields(food.menu.v1.FoodMenu.OfferSet result) {
        if (offersBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0)) {
            offers_ = java.util.Collections.unmodifiableList(offers_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.offers_ = offers_;
        } else {
          result.offers_ = offersBuilder_.build();
        }
      }

      private void buildPartial0(food.menu.v1.FoodMenu.OfferSet result) {
        int from_bitField0_ = bitField0_;
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.OfferSet) {
          return mergeFrom((food.menu.v1.FoodMenu.OfferSet)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.OfferSet other) {
        if (other == food.menu.v1.FoodMenu.OfferSet.getDefaultInstance()) return this;
        if (offersBuilder_ == null) {
          if (!other.offers_.isEmpty()) {
            if (offers_.isEmpty()) {
              offers_ = other.offers_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureOffersIsMutable();
              offers_.addAll(other.offers_);
            }
            onChanged();
          }
        } else {
          if (!other.offers_.isEmpty()) {
            if (offersBuilder_.isEmpty()) {
              offersBuilder_.dispose();
              offersBuilder_ = null;
              offers_ = other.offers_;
              bitField0_ = (bitField0_ & ~0x00000001);
              offersBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getOffersFieldBuilder() : null;
            } else {
              offersBuilder_.addAllMessages(other.offers_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                food.menu.v1.FoodMenu.Offer m =
                    input.readMessage(
                        food.menu.v1.FoodMenu.Offer.parser(),
                        extensionRegistry);
                if (offersBuilder_ == null) {
                  ensureOffersIsMutable();
                  offers_.add(m);
                } else {
                  offersBuilder_.addMessage(m);
                }
                break;
              } // case 10
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.util.List<food.menu.v1.FoodMenu.Offer> offers_ =
        java.util.Collections.emptyList();
      private void ensureOffersIsMutable() {
        if (!((bitField0_ & 0x00000001) != 0)) {
          offers_ = new java.util.ArrayList<food.menu.v1.FoodMenu.Offer>(offers_);
          bitField0_ |= 0x00000001;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          food.menu.v1.FoodMenu.Offer, food.menu.v1.FoodMenu.Offer.Builder, food.menu.v1.FoodMenu.OfferOrBuilder> offersBuilder_;

      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public java.util.List<food.menu.v1.FoodMenu.Offer> getOffersList() {
        if (offersBuilder_ == null) {
          return java.util.Collections.unmodifiableList(offers_);
        } else {
          return offersBuilder_.getMessageList();
        }
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public int getOffersCount() {
        if (offersBuilder_ == null) {
          return offers_.size();
        } else {
          return offersBuilder_.getCount();
        }
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public food.menu.v1.FoodMenu.Offer getOffers(int index) {
        if (offersBuilder_ == null) {
          return offers_.get(index);
        } else {
          return offersBuilder_.getMessage(index);
        }
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public Builder setOffers(
          int index, food.menu.v1.FoodMenu.Offer value) {
        if (offersBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureOffersIsMutable();
          offers_.set(index, value);
          onChanged();
        } else {
          offersBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public Builder setOffers(
          int index, food.menu.v1.FoodMenu.Offer.Builder builderForValue) {
        if (offersBuilder_ == null) {
          ensureOffersIsMutable();
          offers_.set(index, builderForValue.build());
          onChanged();
        } else {
          offersBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public Builder addOffers(food.menu.v1.FoodMenu.Offer value) {
        if (offersBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureOffersIsMutable();
          offers_.add(value);
          onChanged();
        } else {
          offersBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public Builder addOffers(
          int index, food.menu.v1.FoodMenu.Offer value) {
        if (offersBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureOffersIsMutable();
          offers_.add(index, value);
          onChanged();
        } else {
          offersBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public Builder addOffers(
          food.menu.v1.FoodMenu.Offer.Builder builderForValue) {
        if (offersBuilder_ == null) {
          ensureOffersIsMutable();
          offers_.add(builderForValue.build());
          onChanged();
        } else {
          offersBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public Builder addOffers(
          int index, food.menu.v1.FoodMenu.Offer.Builder builderForValue) {
        if (offersBuilder_ == null) {
          ensureOffersIsMutable();
          offers_.add(index, builderForValue.build());
          onChanged();
        } else {
          offersBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public Builder addAllOffers(
          java.lang.Iterable<? extends food.menu.v1.FoodMenu.Offer> values) {
        if (offersBuilder_ == null) {
          ensureOffersIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, offers_);
          onChanged();
        } else {
          offersBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public Builder clearOffers() {
        if (offersBuilder_ == null) {
          offers_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          offersBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public Builder removeOffers(int index) {
        if (offersBuilder_ == null) {
          ensureOffersIsMutable();
          offers_.remove(index);
          onChanged();
        } else {
          offersBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public food.menu.v1.FoodMenu.Offer.Builder getOffersBuilder(
          int index) {
        return getOffersFieldBuilder().getBuilder(index);
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public food.menu.v1.FoodMenu.OfferOrBuilder getOffersOrBuilder(
          int index) {
        if (offersBuilder_ == null) {
          return offers_.get(index);  } else {
          return offersBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public java.util.List<? extends food.menu.v1.FoodMenu.OfferOrBuilder> 
           getOffersOrBuilderList() {
        if (offersBuilder_ != null) {
          return offersBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(offers_);
        }
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public food.menu.v1.FoodMenu.Offer.Builder addOffersBuilder() {
        return getOffersFieldBuilder().addBuilder(
            food.menu.v1.FoodMenu.Offer.getDefaultInstance());
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public food.menu.v1.FoodMenu.Offer.Builder addOffersBuilder(
          int index) {
        return getOffersFieldBuilder().addBuilder(
            index, food.menu.v1.FoodMenu.Offer.getDefaultInstance());
      }
      /**
       * <pre>
       * List of possible offers.
       * Required.
       * </pre>
       *
       * <code>repeated .food.menu.v1.Offer offers = 1;</code>
       */
      public java.util.List<food.menu.v1.FoodMenu.Offer.Builder> 
           getOffersBuilderList() {
        return getOffersFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          food.menu.v1.FoodMenu.Offer, food.menu.v1.FoodMenu.Offer.Builder, food.menu.v1.FoodMenu.OfferOrBuilder> 
          getOffersFieldBuilder() {
        if (offersBuilder_ == null) {
          offersBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              food.menu.v1.FoodMenu.Offer, food.menu.v1.FoodMenu.Offer.Builder, food.menu.v1.FoodMenu.OfferOrBuilder>(
                  offers_,
                  ((bitField0_ & 0x00000001) != 0),
                  getParentForChildren(),
                  isClean());
          offers_ = null;
        }
        return offersBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.OfferSet)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.OfferSet)
    private static final food.menu.v1.FoodMenu.OfferSet DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.OfferSet();
    }

    public static food.menu.v1.FoodMenu.OfferSet getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<OfferSet>
        PARSER = new com.google.protobuf.AbstractParser<OfferSet>() {
      @java.lang.Override
      public OfferSet parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<OfferSet> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<OfferSet> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.OfferSet getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface OfferOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.Offer)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * Monetary value of the menu item/option on sale. Can be 0 to represent free.
     * Required.
     * </pre>
     *
     * <code>.google.type.Money price = 1;</code>
     * @return Whether the price field is set.
     */
    boolean hasPrice();
    /**
     * <pre>
     * Monetary value of the menu item/option on sale. Can be 0 to represent free.
     * Required.
     * </pre>
     *
     * <code>.google.type.Money price = 1;</code>
     * @return The price.
     */
    com.google.type.Money getPrice();
    /**
     * <pre>
     * Monetary value of the menu item/option on sale. Can be 0 to represent free.
     * Required.
     * </pre>
     *
     * <code>.google.type.Money price = 1;</code>
     */
    com.google.type.MoneyOrBuilder getPriceOrBuilder();
  }
  /**
   * <pre>
   * Represents pricing and availability information for MenuItems and
   * MenuItemOptions.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.Offer}
   */
  public static final class Offer extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.Offer)
      OfferOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Offer.newBuilder() to construct.
    private Offer(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Offer() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new Offer();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Offer_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Offer_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.Offer.class, food.menu.v1.FoodMenu.Offer.Builder.class);
    }

    public static final int PRICE_FIELD_NUMBER = 1;
    private com.google.type.Money price_;
    /**
     * <pre>
     * Monetary value of the menu item/option on sale. Can be 0 to represent free.
     * Required.
     * </pre>
     *
     * <code>.google.type.Money price = 1;</code>
     * @return Whether the price field is set.
     */
    @java.lang.Override
    public boolean hasPrice() {
      return price_ != null;
    }
    /**
     * <pre>
     * Monetary value of the menu item/option on sale. Can be 0 to represent free.
     * Required.
     * </pre>
     *
     * <code>.google.type.Money price = 1;</code>
     * @return The price.
     */
    @java.lang.Override
    public com.google.type.Money getPrice() {
      return price_ == null ? com.google.type.Money.getDefaultInstance() : price_;
    }
    /**
     * <pre>
     * Monetary value of the menu item/option on sale. Can be 0 to represent free.
     * Required.
     * </pre>
     *
     * <code>.google.type.Money price = 1;</code>
     */
    @java.lang.Override
    public com.google.type.MoneyOrBuilder getPriceOrBuilder() {
      return price_ == null ? com.google.type.Money.getDefaultInstance() : price_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (price_ != null) {
        output.writeMessage(1, getPrice());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (price_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getPrice());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.Offer)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.Offer other = (food.menu.v1.FoodMenu.Offer) obj;

      if (hasPrice() != other.hasPrice()) return false;
      if (hasPrice()) {
        if (!getPrice()
            .equals(other.getPrice())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasPrice()) {
        hash = (37 * hash) + PRICE_FIELD_NUMBER;
        hash = (53 * hash) + getPrice().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.Offer parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Offer parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Offer parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Offer parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Offer parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Offer parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Offer parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Offer parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Offer parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Offer parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Offer parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Offer parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.Offer prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Represents pricing and availability information for MenuItems and
     * MenuItemOptions.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.Offer}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.Offer)
        food.menu.v1.FoodMenu.OfferOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Offer_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Offer_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.Offer.class, food.menu.v1.FoodMenu.Offer.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.Offer.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        price_ = null;
        if (priceBuilder_ != null) {
          priceBuilder_.dispose();
          priceBuilder_ = null;
        }
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Offer_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Offer getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.Offer.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Offer build() {
        food.menu.v1.FoodMenu.Offer result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Offer buildPartial() {
        food.menu.v1.FoodMenu.Offer result = new food.menu.v1.FoodMenu.Offer(this);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartial0(food.menu.v1.FoodMenu.Offer result) {
        int from_bitField0_ = bitField0_;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.price_ = priceBuilder_ == null
              ? price_
              : priceBuilder_.build();
        }
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.Offer) {
          return mergeFrom((food.menu.v1.FoodMenu.Offer)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.Offer other) {
        if (other == food.menu.v1.FoodMenu.Offer.getDefaultInstance()) return this;
        if (other.hasPrice()) {
          mergePrice(other.getPrice());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getPriceFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private com.google.type.Money price_;
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.type.Money, com.google.type.Money.Builder, com.google.type.MoneyOrBuilder> priceBuilder_;
      /**
       * <pre>
       * Monetary value of the menu item/option on sale. Can be 0 to represent free.
       * Required.
       * </pre>
       *
       * <code>.google.type.Money price = 1;</code>
       * @return Whether the price field is set.
       */
      public boolean hasPrice() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * Monetary value of the menu item/option on sale. Can be 0 to represent free.
       * Required.
       * </pre>
       *
       * <code>.google.type.Money price = 1;</code>
       * @return The price.
       */
      public com.google.type.Money getPrice() {
        if (priceBuilder_ == null) {
          return price_ == null ? com.google.type.Money.getDefaultInstance() : price_;
        } else {
          return priceBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Monetary value of the menu item/option on sale. Can be 0 to represent free.
       * Required.
       * </pre>
       *
       * <code>.google.type.Money price = 1;</code>
       */
      public Builder setPrice(com.google.type.Money value) {
        if (priceBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          price_ = value;
        } else {
          priceBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Monetary value of the menu item/option on sale. Can be 0 to represent free.
       * Required.
       * </pre>
       *
       * <code>.google.type.Money price = 1;</code>
       */
      public Builder setPrice(
          com.google.type.Money.Builder builderForValue) {
        if (priceBuilder_ == null) {
          price_ = builderForValue.build();
        } else {
          priceBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Monetary value of the menu item/option on sale. Can be 0 to represent free.
       * Required.
       * </pre>
       *
       * <code>.google.type.Money price = 1;</code>
       */
      public Builder mergePrice(com.google.type.Money value) {
        if (priceBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
            price_ != null &&
            price_ != com.google.type.Money.getDefaultInstance()) {
            getPriceBuilder().mergeFrom(value);
          } else {
            price_ = value;
          }
        } else {
          priceBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Monetary value of the menu item/option on sale. Can be 0 to represent free.
       * Required.
       * </pre>
       *
       * <code>.google.type.Money price = 1;</code>
       */
      public Builder clearPrice() {
        bitField0_ = (bitField0_ & ~0x00000001);
        price_ = null;
        if (priceBuilder_ != null) {
          priceBuilder_.dispose();
          priceBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Monetary value of the menu item/option on sale. Can be 0 to represent free.
       * Required.
       * </pre>
       *
       * <code>.google.type.Money price = 1;</code>
       */
      public com.google.type.Money.Builder getPriceBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getPriceFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Monetary value of the menu item/option on sale. Can be 0 to represent free.
       * Required.
       * </pre>
       *
       * <code>.google.type.Money price = 1;</code>
       */
      public com.google.type.MoneyOrBuilder getPriceOrBuilder() {
        if (priceBuilder_ != null) {
          return priceBuilder_.getMessageOrBuilder();
        } else {
          return price_ == null ?
              com.google.type.Money.getDefaultInstance() : price_;
        }
      }
      /**
       * <pre>
       * Monetary value of the menu item/option on sale. Can be 0 to represent free.
       * Required.
       * </pre>
       *
       * <code>.google.type.Money price = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.type.Money, com.google.type.Money.Builder, com.google.type.MoneyOrBuilder> 
          getPriceFieldBuilder() {
        if (priceBuilder_ == null) {
          priceBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              com.google.type.Money, com.google.type.Money.Builder, com.google.type.MoneyOrBuilder>(
                  getPrice(),
                  getParentForChildren(),
                  isClean());
          price_ = null;
        }
        return priceBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.Offer)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.Offer)
    private static final food.menu.v1.FoodMenu.Offer DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.Offer();
    }

    public static food.menu.v1.FoodMenu.Offer getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<Offer>
        PARSER = new com.google.protobuf.AbstractParser<Offer>() {
      @java.lang.Override
      public Offer parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<Offer> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<Offer> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.Offer getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface DisclaimerOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.Disclaimer)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * Body of the disclaimer text to be shown to the user.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField text = 1;</code>
     * @return Whether the text field is set.
     */
    boolean hasText();
    /**
     * <pre>
     * Body of the disclaimer text to be shown to the user.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField text = 1;</code>
     * @return The text.
     */
    food.menu.v1.FoodMenu.TextField getText();
    /**
     * <pre>
     * Body of the disclaimer text to be shown to the user.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField text = 1;</code>
     */
    food.menu.v1.FoodMenu.TextFieldOrBuilder getTextOrBuilder();

    /**
     * <pre>
     * URL containing more information about the disclaimer.
     * Optional.
     * </pre>
     *
     * <code>string uri = 2;</code>
     * @return The uri.
     */
    java.lang.String getUri();
    /**
     * <pre>
     * URL containing more information about the disclaimer.
     * Optional.
     * </pre>
     *
     * <code>string uri = 2;</code>
     * @return The bytes for uri.
     */
    com.google.protobuf.ByteString
        getUriBytes();
  }
  /**
   * <pre>
   * Partner provided disclaimer shown to the user. Contains a text disclaimer
   * along with an optional URL for more information.
   * Some example include: associated medical risks/warnings, any additional
   * fees/gratutity, etc.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.Disclaimer}
   */
  public static final class Disclaimer extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.Disclaimer)
      DisclaimerOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Disclaimer.newBuilder() to construct.
    private Disclaimer(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Disclaimer() {
      uri_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new Disclaimer();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Disclaimer_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Disclaimer_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.Disclaimer.class, food.menu.v1.FoodMenu.Disclaimer.Builder.class);
    }

    public static final int TEXT_FIELD_NUMBER = 1;
    private food.menu.v1.FoodMenu.TextField text_;
    /**
     * <pre>
     * Body of the disclaimer text to be shown to the user.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField text = 1;</code>
     * @return Whether the text field is set.
     */
    @java.lang.Override
    public boolean hasText() {
      return text_ != null;
    }
    /**
     * <pre>
     * Body of the disclaimer text to be shown to the user.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField text = 1;</code>
     * @return The text.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextField getText() {
      return text_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : text_;
    }
    /**
     * <pre>
     * Body of the disclaimer text to be shown to the user.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField text = 1;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextFieldOrBuilder getTextOrBuilder() {
      return text_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : text_;
    }

    public static final int URI_FIELD_NUMBER = 2;
    @SuppressWarnings("serial")
    private volatile java.lang.Object uri_ = "";
    /**
     * <pre>
     * URL containing more information about the disclaimer.
     * Optional.
     * </pre>
     *
     * <code>string uri = 2;</code>
     * @return The uri.
     */
    @java.lang.Override
    public java.lang.String getUri() {
      java.lang.Object ref = uri_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        uri_ = s;
        return s;
      }
    }
    /**
     * <pre>
     * URL containing more information about the disclaimer.
     * Optional.
     * </pre>
     *
     * <code>string uri = 2;</code>
     * @return The bytes for uri.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getUriBytes() {
      java.lang.Object ref = uri_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        uri_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (text_ != null) {
        output.writeMessage(1, getText());
      }
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(uri_)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, uri_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (text_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getText());
      }
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(uri_)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, uri_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.Disclaimer)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.Disclaimer other = (food.menu.v1.FoodMenu.Disclaimer) obj;

      if (hasText() != other.hasText()) return false;
      if (hasText()) {
        if (!getText()
            .equals(other.getText())) return false;
      }
      if (!getUri()
          .equals(other.getUri())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasText()) {
        hash = (37 * hash) + TEXT_FIELD_NUMBER;
        hash = (53 * hash) + getText().hashCode();
      }
      hash = (37 * hash) + URI_FIELD_NUMBER;
      hash = (53 * hash) + getUri().hashCode();
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.Disclaimer parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Disclaimer parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Disclaimer parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Disclaimer parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Disclaimer parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Disclaimer parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Disclaimer parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Disclaimer parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Disclaimer parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Disclaimer parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Disclaimer parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Disclaimer parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.Disclaimer prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Partner provided disclaimer shown to the user. Contains a text disclaimer
     * along with an optional URL for more information.
     * Some example include: associated medical risks/warnings, any additional
     * fees/gratutity, etc.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.Disclaimer}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.Disclaimer)
        food.menu.v1.FoodMenu.DisclaimerOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Disclaimer_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Disclaimer_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.Disclaimer.class, food.menu.v1.FoodMenu.Disclaimer.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.Disclaimer.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        text_ = null;
        if (textBuilder_ != null) {
          textBuilder_.dispose();
          textBuilder_ = null;
        }
        uri_ = "";
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Disclaimer_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Disclaimer getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.Disclaimer.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Disclaimer build() {
        food.menu.v1.FoodMenu.Disclaimer result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Disclaimer buildPartial() {
        food.menu.v1.FoodMenu.Disclaimer result = new food.menu.v1.FoodMenu.Disclaimer(this);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartial0(food.menu.v1.FoodMenu.Disclaimer result) {
        int from_bitField0_ = bitField0_;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.text_ = textBuilder_ == null
              ? text_
              : textBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.uri_ = uri_;
        }
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.Disclaimer) {
          return mergeFrom((food.menu.v1.FoodMenu.Disclaimer)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.Disclaimer other) {
        if (other == food.menu.v1.FoodMenu.Disclaimer.getDefaultInstance()) return this;
        if (other.hasText()) {
          mergeText(other.getText());
        }
        if (!other.getUri().isEmpty()) {
          uri_ = other.uri_;
          bitField0_ |= 0x00000002;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getTextFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                uri_ = input.readStringRequireUtf8();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private food.menu.v1.FoodMenu.TextField text_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> textBuilder_;
      /**
       * <pre>
       * Body of the disclaimer text to be shown to the user.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text = 1;</code>
       * @return Whether the text field is set.
       */
      public boolean hasText() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * Body of the disclaimer text to be shown to the user.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text = 1;</code>
       * @return The text.
       */
      public food.menu.v1.FoodMenu.TextField getText() {
        if (textBuilder_ == null) {
          return text_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : text_;
        } else {
          return textBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Body of the disclaimer text to be shown to the user.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text = 1;</code>
       */
      public Builder setText(food.menu.v1.FoodMenu.TextField value) {
        if (textBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          text_ = value;
        } else {
          textBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Body of the disclaimer text to be shown to the user.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text = 1;</code>
       */
      public Builder setText(
          food.menu.v1.FoodMenu.TextField.Builder builderForValue) {
        if (textBuilder_ == null) {
          text_ = builderForValue.build();
        } else {
          textBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Body of the disclaimer text to be shown to the user.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text = 1;</code>
       */
      public Builder mergeText(food.menu.v1.FoodMenu.TextField value) {
        if (textBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
            text_ != null &&
            text_ != food.menu.v1.FoodMenu.TextField.getDefaultInstance()) {
            getTextBuilder().mergeFrom(value);
          } else {
            text_ = value;
          }
        } else {
          textBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Body of the disclaimer text to be shown to the user.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text = 1;</code>
       */
      public Builder clearText() {
        bitField0_ = (bitField0_ & ~0x00000001);
        text_ = null;
        if (textBuilder_ != null) {
          textBuilder_.dispose();
          textBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Body of the disclaimer text to be shown to the user.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text = 1;</code>
       */
      public food.menu.v1.FoodMenu.TextField.Builder getTextBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getTextFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Body of the disclaimer text to be shown to the user.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text = 1;</code>
       */
      public food.menu.v1.FoodMenu.TextFieldOrBuilder getTextOrBuilder() {
        if (textBuilder_ != null) {
          return textBuilder_.getMessageOrBuilder();
        } else {
          return text_ == null ?
              food.menu.v1.FoodMenu.TextField.getDefaultInstance() : text_;
        }
      }
      /**
       * <pre>
       * Body of the disclaimer text to be shown to the user.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> 
          getTextFieldBuilder() {
        if (textBuilder_ == null) {
          textBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder>(
                  getText(),
                  getParentForChildren(),
                  isClean());
          text_ = null;
        }
        return textBuilder_;
      }

      private java.lang.Object uri_ = "";
      /**
       * <pre>
       * URL containing more information about the disclaimer.
       * Optional.
       * </pre>
       *
       * <code>string uri = 2;</code>
       * @return The uri.
       */
      public java.lang.String getUri() {
        java.lang.Object ref = uri_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          uri_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * URL containing more information about the disclaimer.
       * Optional.
       * </pre>
       *
       * <code>string uri = 2;</code>
       * @return The bytes for uri.
       */
      public com.google.protobuf.ByteString
          getUriBytes() {
        java.lang.Object ref = uri_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          uri_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * URL containing more information about the disclaimer.
       * Optional.
       * </pre>
       *
       * <code>string uri = 2;</code>
       * @param value The uri to set.
       * @return This builder for chaining.
       */
      public Builder setUri(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        uri_ = value;
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * URL containing more information about the disclaimer.
       * Optional.
       * </pre>
       *
       * <code>string uri = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearUri() {
        uri_ = getDefaultInstance().getUri();
        bitField0_ = (bitField0_ & ~0x00000002);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * URL containing more information about the disclaimer.
       * Optional.
       * </pre>
       *
       * <code>string uri = 2;</code>
       * @param value The bytes for uri to set.
       * @return This builder for chaining.
       */
      public Builder setUriBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        uri_ = value;
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.Disclaimer)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.Disclaimer)
    private static final food.menu.v1.FoodMenu.Disclaimer DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.Disclaimer();
    }

    public static food.menu.v1.FoodMenu.Disclaimer getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<Disclaimer>
        PARSER = new com.google.protobuf.AbstractParser<Disclaimer>() {
      @java.lang.Override
      public Disclaimer parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<Disclaimer> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<Disclaimer> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.Disclaimer getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface TextFieldOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.TextField)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * Per-locale text values.
     *
     * If there is only one desired locale support, then the language_code within
     * each text is not required to be set and the language will be inferred from
     * the default language of the menu.
     *
     * If there are multiple texts across different locales, then the
     * language_code must be set for each text. The first text in the list is
     * considered the preferred representation.
     * Required.
     * </pre>
     *
     * <code>repeated .google.type.LocalizedText text = 1;</code>
     */
    java.util.List<com.google.type.LocalizedText> 
        getTextList();
    /**
     * <pre>
     * Per-locale text values.
     *
     * If there is only one desired locale support, then the language_code within
     * each text is not required to be set and the language will be inferred from
     * the default language of the menu.
     *
     * If there are multiple texts across different locales, then the
     * language_code must be set for each text. The first text in the list is
     * considered the preferred representation.
     * Required.
     * </pre>
     *
     * <code>repeated .google.type.LocalizedText text = 1;</code>
     */
    com.google.type.LocalizedText getText(int index);
    /**
     * <pre>
     * Per-locale text values.
     *
     * If there is only one desired locale support, then the language_code within
     * each text is not required to be set and the language will be inferred from
     * the default language of the menu.
     *
     * If there are multiple texts across different locales, then the
     * language_code must be set for each text. The first text in the list is
     * considered the preferred representation.
     * Required.
     * </pre>
     *
     * <code>repeated .google.type.LocalizedText text = 1;</code>
     */
    int getTextCount();
    /**
     * <pre>
     * Per-locale text values.
     *
     * If there is only one desired locale support, then the language_code within
     * each text is not required to be set and the language will be inferred from
     * the default language of the menu.
     *
     * If there are multiple texts across different locales, then the
     * language_code must be set for each text. The first text in the list is
     * considered the preferred representation.
     * Required.
     * </pre>
     *
     * <code>repeated .google.type.LocalizedText text = 1;</code>
     */
    java.util.List<? extends com.google.type.LocalizedTextOrBuilder> 
        getTextOrBuilderList();
    /**
     * <pre>
     * Per-locale text values.
     *
     * If there is only one desired locale support, then the language_code within
     * each text is not required to be set and the language will be inferred from
     * the default language of the menu.
     *
     * If there are multiple texts across different locales, then the
     * language_code must be set for each text. The first text in the list is
     * considered the preferred representation.
     * Required.
     * </pre>
     *
     * <code>repeated .google.type.LocalizedText text = 1;</code>
     */
    com.google.type.LocalizedTextOrBuilder getTextOrBuilder(
        int index);
  }
  /**
   * <pre>
   * A text payload that contains one or more localized values.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.TextField}
   */
  public static final class TextField extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.TextField)
      TextFieldOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use TextField.newBuilder() to construct.
    private TextField(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private TextField() {
      text_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new TextField();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_TextField_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_TextField_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.TextField.class, food.menu.v1.FoodMenu.TextField.Builder.class);
    }

    public static final int TEXT_FIELD_NUMBER = 1;
    @SuppressWarnings("serial")
    private java.util.List<com.google.type.LocalizedText> text_;
    /**
     * <pre>
     * Per-locale text values.
     *
     * If there is only one desired locale support, then the language_code within
     * each text is not required to be set and the language will be inferred from
     * the default language of the menu.
     *
     * If there are multiple texts across different locales, then the
     * language_code must be set for each text. The first text in the list is
     * considered the preferred representation.
     * Required.
     * </pre>
     *
     * <code>repeated .google.type.LocalizedText text = 1;</code>
     */
    @java.lang.Override
    public java.util.List<com.google.type.LocalizedText> getTextList() {
      return text_;
    }
    /**
     * <pre>
     * Per-locale text values.
     *
     * If there is only one desired locale support, then the language_code within
     * each text is not required to be set and the language will be inferred from
     * the default language of the menu.
     *
     * If there are multiple texts across different locales, then the
     * language_code must be set for each text. The first text in the list is
     * considered the preferred representation.
     * Required.
     * </pre>
     *
     * <code>repeated .google.type.LocalizedText text = 1;</code>
     */
    @java.lang.Override
    public java.util.List<? extends com.google.type.LocalizedTextOrBuilder> 
        getTextOrBuilderList() {
      return text_;
    }
    /**
     * <pre>
     * Per-locale text values.
     *
     * If there is only one desired locale support, then the language_code within
     * each text is not required to be set and the language will be inferred from
     * the default language of the menu.
     *
     * If there are multiple texts across different locales, then the
     * language_code must be set for each text. The first text in the list is
     * considered the preferred representation.
     * Required.
     * </pre>
     *
     * <code>repeated .google.type.LocalizedText text = 1;</code>
     */
    @java.lang.Override
    public int getTextCount() {
      return text_.size();
    }
    /**
     * <pre>
     * Per-locale text values.
     *
     * If there is only one desired locale support, then the language_code within
     * each text is not required to be set and the language will be inferred from
     * the default language of the menu.
     *
     * If there are multiple texts across different locales, then the
     * language_code must be set for each text. The first text in the list is
     * considered the preferred representation.
     * Required.
     * </pre>
     *
     * <code>repeated .google.type.LocalizedText text = 1;</code>
     */
    @java.lang.Override
    public com.google.type.LocalizedText getText(int index) {
      return text_.get(index);
    }
    /**
     * <pre>
     * Per-locale text values.
     *
     * If there is only one desired locale support, then the language_code within
     * each text is not required to be set and the language will be inferred from
     * the default language of the menu.
     *
     * If there are multiple texts across different locales, then the
     * language_code must be set for each text. The first text in the list is
     * considered the preferred representation.
     * Required.
     * </pre>
     *
     * <code>repeated .google.type.LocalizedText text = 1;</code>
     */
    @java.lang.Override
    public com.google.type.LocalizedTextOrBuilder getTextOrBuilder(
        int index) {
      return text_.get(index);
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      for (int i = 0; i < text_.size(); i++) {
        output.writeMessage(1, text_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < text_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, text_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.TextField)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.TextField other = (food.menu.v1.FoodMenu.TextField) obj;

      if (!getTextList()
          .equals(other.getTextList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (getTextCount() > 0) {
        hash = (37 * hash) + TEXT_FIELD_NUMBER;
        hash = (53 * hash) + getTextList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.TextField parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.TextField parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.TextField parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.TextField parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.TextField parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.TextField parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.TextField parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.TextField parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.TextField parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.TextField parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.TextField parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.TextField parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.TextField prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * A text payload that contains one or more localized values.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.TextField}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.TextField)
        food.menu.v1.FoodMenu.TextFieldOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_TextField_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_TextField_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.TextField.class, food.menu.v1.FoodMenu.TextField.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.TextField.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        if (textBuilder_ == null) {
          text_ = java.util.Collections.emptyList();
        } else {
          text_ = null;
          textBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_TextField_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.TextField getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.TextField.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.TextField build() {
        food.menu.v1.FoodMenu.TextField result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.TextField buildPartial() {
        food.menu.v1.FoodMenu.TextField result = new food.menu.v1.FoodMenu.TextField(this);
        buildPartialRepeatedFields(result);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartialRepeatedFields(food.menu.v1.FoodMenu.TextField result) {
        if (textBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0)) {
            text_ = java.util.Collections.unmodifiableList(text_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.text_ = text_;
        } else {
          result.text_ = textBuilder_.build();
        }
      }

      private void buildPartial0(food.menu.v1.FoodMenu.TextField result) {
        int from_bitField0_ = bitField0_;
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.TextField) {
          return mergeFrom((food.menu.v1.FoodMenu.TextField)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.TextField other) {
        if (other == food.menu.v1.FoodMenu.TextField.getDefaultInstance()) return this;
        if (textBuilder_ == null) {
          if (!other.text_.isEmpty()) {
            if (text_.isEmpty()) {
              text_ = other.text_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureTextIsMutable();
              text_.addAll(other.text_);
            }
            onChanged();
          }
        } else {
          if (!other.text_.isEmpty()) {
            if (textBuilder_.isEmpty()) {
              textBuilder_.dispose();
              textBuilder_ = null;
              text_ = other.text_;
              bitField0_ = (bitField0_ & ~0x00000001);
              textBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getTextFieldBuilder() : null;
            } else {
              textBuilder_.addAllMessages(other.text_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                com.google.type.LocalizedText m =
                    input.readMessage(
                        com.google.type.LocalizedText.parser(),
                        extensionRegistry);
                if (textBuilder_ == null) {
                  ensureTextIsMutable();
                  text_.add(m);
                } else {
                  textBuilder_.addMessage(m);
                }
                break;
              } // case 10
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.util.List<com.google.type.LocalizedText> text_ =
        java.util.Collections.emptyList();
      private void ensureTextIsMutable() {
        if (!((bitField0_ & 0x00000001) != 0)) {
          text_ = new java.util.ArrayList<com.google.type.LocalizedText>(text_);
          bitField0_ |= 0x00000001;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          com.google.type.LocalizedText, com.google.type.LocalizedText.Builder, com.google.type.LocalizedTextOrBuilder> textBuilder_;

      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public java.util.List<com.google.type.LocalizedText> getTextList() {
        if (textBuilder_ == null) {
          return java.util.Collections.unmodifiableList(text_);
        } else {
          return textBuilder_.getMessageList();
        }
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public int getTextCount() {
        if (textBuilder_ == null) {
          return text_.size();
        } else {
          return textBuilder_.getCount();
        }
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public com.google.type.LocalizedText getText(int index) {
        if (textBuilder_ == null) {
          return text_.get(index);
        } else {
          return textBuilder_.getMessage(index);
        }
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public Builder setText(
          int index, com.google.type.LocalizedText value) {
        if (textBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureTextIsMutable();
          text_.set(index, value);
          onChanged();
        } else {
          textBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public Builder setText(
          int index, com.google.type.LocalizedText.Builder builderForValue) {
        if (textBuilder_ == null) {
          ensureTextIsMutable();
          text_.set(index, builderForValue.build());
          onChanged();
        } else {
          textBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public Builder addText(com.google.type.LocalizedText value) {
        if (textBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureTextIsMutable();
          text_.add(value);
          onChanged();
        } else {
          textBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public Builder addText(
          int index, com.google.type.LocalizedText value) {
        if (textBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureTextIsMutable();
          text_.add(index, value);
          onChanged();
        } else {
          textBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public Builder addText(
          com.google.type.LocalizedText.Builder builderForValue) {
        if (textBuilder_ == null) {
          ensureTextIsMutable();
          text_.add(builderForValue.build());
          onChanged();
        } else {
          textBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public Builder addText(
          int index, com.google.type.LocalizedText.Builder builderForValue) {
        if (textBuilder_ == null) {
          ensureTextIsMutable();
          text_.add(index, builderForValue.build());
          onChanged();
        } else {
          textBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public Builder addAllText(
          java.lang.Iterable<? extends com.google.type.LocalizedText> values) {
        if (textBuilder_ == null) {
          ensureTextIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, text_);
          onChanged();
        } else {
          textBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public Builder clearText() {
        if (textBuilder_ == null) {
          text_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          textBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public Builder removeText(int index) {
        if (textBuilder_ == null) {
          ensureTextIsMutable();
          text_.remove(index);
          onChanged();
        } else {
          textBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public com.google.type.LocalizedText.Builder getTextBuilder(
          int index) {
        return getTextFieldBuilder().getBuilder(index);
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public com.google.type.LocalizedTextOrBuilder getTextOrBuilder(
          int index) {
        if (textBuilder_ == null) {
          return text_.get(index);  } else {
          return textBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public java.util.List<? extends com.google.type.LocalizedTextOrBuilder> 
           getTextOrBuilderList() {
        if (textBuilder_ != null) {
          return textBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(text_);
        }
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public com.google.type.LocalizedText.Builder addTextBuilder() {
        return getTextFieldBuilder().addBuilder(
            com.google.type.LocalizedText.getDefaultInstance());
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public com.google.type.LocalizedText.Builder addTextBuilder(
          int index) {
        return getTextFieldBuilder().addBuilder(
            index, com.google.type.LocalizedText.getDefaultInstance());
      }
      /**
       * <pre>
       * Per-locale text values.
       *
       * If there is only one desired locale support, then the language_code within
       * each text is not required to be set and the language will be inferred from
       * the default language of the menu.
       *
       * If there are multiple texts across different locales, then the
       * language_code must be set for each text. The first text in the list is
       * considered the preferred representation.
       * Required.
       * </pre>
       *
       * <code>repeated .google.type.LocalizedText text = 1;</code>
       */
      public java.util.List<com.google.type.LocalizedText.Builder> 
           getTextBuilderList() {
        return getTextFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          com.google.type.LocalizedText, com.google.type.LocalizedText.Builder, com.google.type.LocalizedTextOrBuilder> 
          getTextFieldBuilder() {
        if (textBuilder_ == null) {
          textBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              com.google.type.LocalizedText, com.google.type.LocalizedText.Builder, com.google.type.LocalizedTextOrBuilder>(
                  text_,
                  ((bitField0_ & 0x00000001) != 0),
                  getParentForChildren(),
                  isClean());
          text_ = null;
        }
        return textBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.TextField)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.TextField)
    private static final food.menu.v1.FoodMenu.TextField DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.TextField();
    }

    public static food.menu.v1.FoodMenu.TextField getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<TextField>
        PARSER = new com.google.protobuf.AbstractParser<TextField>() {
      @java.lang.Override
      public TextField parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<TextField> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<TextField> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.TextField getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface ImageOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.Image)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * URL containing the raw pixels of the image.
     * Required.
     * </pre>
     *
     * <code>string uri = 1;</code>
     * @return The uri.
     */
    java.lang.String getUri();
    /**
     * <pre>
     * URL containing the raw pixels of the image.
     * Required.
     * </pre>
     *
     * <code>string uri = 1;</code>
     * @return The bytes for uri.
     */
    com.google.protobuf.ByteString
        getUriBytes();
  }
  /**
   * <pre>
   * Represents an image associated with a menu entity.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.Image}
   */
  public static final class Image extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.Image)
      ImageOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Image.newBuilder() to construct.
    private Image(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Image() {
      uri_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new Image();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Image_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Image_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.Image.class, food.menu.v1.FoodMenu.Image.Builder.class);
    }

    public static final int URI_FIELD_NUMBER = 1;
    @SuppressWarnings("serial")
    private volatile java.lang.Object uri_ = "";
    /**
     * <pre>
     * URL containing the raw pixels of the image.
     * Required.
     * </pre>
     *
     * <code>string uri = 1;</code>
     * @return The uri.
     */
    @java.lang.Override
    public java.lang.String getUri() {
      java.lang.Object ref = uri_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        uri_ = s;
        return s;
      }
    }
    /**
     * <pre>
     * URL containing the raw pixels of the image.
     * Required.
     * </pre>
     *
     * <code>string uri = 1;</code>
     * @return The bytes for uri.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getUriBytes() {
      java.lang.Object ref = uri_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        uri_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(uri_)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, uri_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(uri_)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, uri_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.Image)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.Image other = (food.menu.v1.FoodMenu.Image) obj;

      if (!getUri()
          .equals(other.getUri())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      hash = (37 * hash) + URI_FIELD_NUMBER;
      hash = (53 * hash) + getUri().hashCode();
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.Image parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Image parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Image parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Image parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Image parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Image parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Image parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Image parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Image parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Image parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Image parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Image parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.Image prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Represents an image associated with a menu entity.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.Image}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.Image)
        food.menu.v1.FoodMenu.ImageOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Image_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Image_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.Image.class, food.menu.v1.FoodMenu.Image.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.Image.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        uri_ = "";
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Image_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Image getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.Image.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Image build() {
        food.menu.v1.FoodMenu.Image result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Image buildPartial() {
        food.menu.v1.FoodMenu.Image result = new food.menu.v1.FoodMenu.Image(this);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartial0(food.menu.v1.FoodMenu.Image result) {
        int from_bitField0_ = bitField0_;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.uri_ = uri_;
        }
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.Image) {
          return mergeFrom((food.menu.v1.FoodMenu.Image)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.Image other) {
        if (other == food.menu.v1.FoodMenu.Image.getDefaultInstance()) return this;
        if (!other.getUri().isEmpty()) {
          uri_ = other.uri_;
          bitField0_ |= 0x00000001;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                uri_ = input.readStringRequireUtf8();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object uri_ = "";
      /**
       * <pre>
       * URL containing the raw pixels of the image.
       * Required.
       * </pre>
       *
       * <code>string uri = 1;</code>
       * @return The uri.
       */
      public java.lang.String getUri() {
        java.lang.Object ref = uri_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          uri_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * URL containing the raw pixels of the image.
       * Required.
       * </pre>
       *
       * <code>string uri = 1;</code>
       * @return The bytes for uri.
       */
      public com.google.protobuf.ByteString
          getUriBytes() {
        java.lang.Object ref = uri_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          uri_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * URL containing the raw pixels of the image.
       * Required.
       * </pre>
       *
       * <code>string uri = 1;</code>
       * @param value The uri to set.
       * @return This builder for chaining.
       */
      public Builder setUri(
          java.lang.String value) {
        if (value == null) { throw new NullPointerException(); }
        uri_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * URL containing the raw pixels of the image.
       * Required.
       * </pre>
       *
       * <code>string uri = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearUri() {
        uri_ = getDefaultInstance().getUri();
        bitField0_ = (bitField0_ & ~0x00000001);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * URL containing the raw pixels of the image.
       * Required.
       * </pre>
       *
       * <code>string uri = 1;</code>
       * @param value The bytes for uri to set.
       * @return This builder for chaining.
       */
      public Builder setUriBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) { throw new NullPointerException(); }
        checkByteStringIsUtf8(value);
        uri_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.Image)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.Image)
    private static final food.menu.v1.FoodMenu.Image DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.Image();
    }

    public static food.menu.v1.FoodMenu.Image getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<Image>
        PARSER = new com.google.protobuf.AbstractParser<Image>() {
      @java.lang.Override
      public Image parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<Image> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<Image> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.Image getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface MenuItemOptionPropertyOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.MenuItemOptionProperty)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * The type of this option property.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty.PropertyType property_type = 1;</code>
     * @return The enum numeric value on the wire for propertyType.
     */
    int getPropertyTypeValue();
    /**
     * <pre>
     * The type of this option property.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty.PropertyType property_type = 1;</code>
     * @return The propertyType.
     */
    food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyType getPropertyType();

    /**
     * <pre>
     * A well-defined value for the option property. Currently only expected
     * if the property_type is PIZZA_SIDE.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty.PropertyValue property_val = 2;</code>
     * @return Whether the propertyVal field is set.
     */
    boolean hasPropertyVal();
    /**
     * <pre>
     * A well-defined value for the option property. Currently only expected
     * if the property_type is PIZZA_SIDE.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty.PropertyValue property_val = 2;</code>
     * @return The enum numeric value on the wire for propertyVal.
     */
    int getPropertyValValue();
    /**
     * <pre>
     * A well-defined value for the option property. Currently only expected
     * if the property_type is PIZZA_SIDE.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty.PropertyValue property_val = 2;</code>
     * @return The propertyVal.
     */
    food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyValue getPropertyVal();

    /**
     * <pre>
     * A free-form text for the value of the property. Expected for
     * property_type OPTION and SIZE.
     * </pre>
     *
     * <code>.food.menu.v1.TextField text_val = 3;</code>
     * @return Whether the textVal field is set.
     */
    boolean hasTextVal();
    /**
     * <pre>
     * A free-form text for the value of the property. Expected for
     * property_type OPTION and SIZE.
     * </pre>
     *
     * <code>.food.menu.v1.TextField text_val = 3;</code>
     * @return The textVal.
     */
    food.menu.v1.FoodMenu.TextField getTextVal();
    /**
     * <pre>
     * A free-form text for the value of the property. Expected for
     * property_type OPTION and SIZE.
     * </pre>
     *
     * <code>.food.menu.v1.TextField text_val = 3;</code>
     */
    food.menu.v1.FoodMenu.TextFieldOrBuilder getTextValOrBuilder();

    food.menu.v1.FoodMenu.MenuItemOptionProperty.ValueCase getValueCase();
  }
  /**
   * <pre>
   * Describes the property of a menu item option and its value.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.MenuItemOptionProperty}
   */
  public static final class MenuItemOptionProperty extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.MenuItemOptionProperty)
      MenuItemOptionPropertyOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use MenuItemOptionProperty.newBuilder() to construct.
    private MenuItemOptionProperty(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private MenuItemOptionProperty() {
      propertyType_ = 0;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new MenuItemOptionProperty();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemOptionProperty_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemOptionProperty_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.MenuItemOptionProperty.class, food.menu.v1.FoodMenu.MenuItemOptionProperty.Builder.class);
    }

    /**
     * <pre>
     * Types of property that the option is for.
     * </pre>
     *
     * Protobuf enum {@code food.menu.v1.MenuItemOptionProperty.PropertyType}
     */
    public enum PropertyType
        implements com.google.protobuf.ProtocolMessageEnum {
      /**
       * <pre>
       * Do not use. The property type is not explicitly specified.
       * </pre>
       *
       * <code>UNKNOWN_PROPERTY_TYPE = 0;</code>
       */
      UNKNOWN_PROPERTY_TYPE(0),
      /**
       * <pre>
       * A generic menu item option property, which is not one of the more
       * specific types below. Use this if the property is not of type
       * SIZE or PIZZA_SIDE.
       * </pre>
       *
       * <code>OPTION = 1;</code>
       */
      OPTION(1),
      /**
       * <pre>
       * Denotes the menu item option property of size (e.g. small, medium, or
       * large).
       * </pre>
       *
       * <code>SIZE = 2;</code>
       */
      SIZE(2),
      /**
       * <pre>
       * Property specific to pizzas. For example: this MenuItemOption is only
       * valid for a portion/whole pizza, such as mushroom toppings on the left
       * side, right side, or whole pizza).
       * </pre>
       *
       * <code>PIZZA_SIDE = 3;</code>
       */
      PIZZA_SIDE(3),
      UNRECOGNIZED(-1),
      ;

      /**
       * <pre>
       * Do not use. The property type is not explicitly specified.
       * </pre>
       *
       * <code>UNKNOWN_PROPERTY_TYPE = 0;</code>
       */
      public static final int UNKNOWN_PROPERTY_TYPE_VALUE = 0;
      /**
       * <pre>
       * A generic menu item option property, which is not one of the more
       * specific types below. Use this if the property is not of type
       * SIZE or PIZZA_SIDE.
       * </pre>
       *
       * <code>OPTION = 1;</code>
       */
      public static final int OPTION_VALUE = 1;
      /**
       * <pre>
       * Denotes the menu item option property of size (e.g. small, medium, or
       * large).
       * </pre>
       *
       * <code>SIZE = 2;</code>
       */
      public static final int SIZE_VALUE = 2;
      /**
       * <pre>
       * Property specific to pizzas. For example: this MenuItemOption is only
       * valid for a portion/whole pizza, such as mushroom toppings on the left
       * side, right side, or whole pizza).
       * </pre>
       *
       * <code>PIZZA_SIDE = 3;</code>
       */
      public static final int PIZZA_SIDE_VALUE = 3;


      public final int getNumber() {
        if (this == UNRECOGNIZED) {
          throw new java.lang.IllegalArgumentException(
              "Can't get the number of an unknown enum value.");
        }
        return value;
      }

      /**
       * @param value The numeric wire value of the corresponding enum entry.
       * @return The enum associated with the given numeric wire value.
       * @deprecated Use {@link #forNumber(int)} instead.
       */
      @java.lang.Deprecated
      public static PropertyType valueOf(int value) {
        return forNumber(value);
      }

      /**
       * @param value The numeric wire value of the corresponding enum entry.
       * @return The enum associated with the given numeric wire value.
       */
      public static PropertyType forNumber(int value) {
        switch (value) {
          case 0: return UNKNOWN_PROPERTY_TYPE;
          case 1: return OPTION;
          case 2: return SIZE;
          case 3: return PIZZA_SIDE;
          default: return null;
        }
      }

      public static com.google.protobuf.Internal.EnumLiteMap<PropertyType>
          internalGetValueMap() {
        return internalValueMap;
      }
      private static final com.google.protobuf.Internal.EnumLiteMap<
          PropertyType> internalValueMap =
            new com.google.protobuf.Internal.EnumLiteMap<PropertyType>() {
              public PropertyType findValueByNumber(int number) {
                return PropertyType.forNumber(number);
              }
            };

      public final com.google.protobuf.Descriptors.EnumValueDescriptor
          getValueDescriptor() {
        if (this == UNRECOGNIZED) {
          throw new java.lang.IllegalStateException(
              "Can't get the descriptor of an unrecognized enum value.");
        }
        return getDescriptor().getValues().get(ordinal());
      }
      public final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptorForType() {
        return getDescriptor();
      }
      public static final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.MenuItemOptionProperty.getDescriptor().getEnumTypes().get(0);
      }

      private static final PropertyType[] VALUES = values();

      public static PropertyType valueOf(
          com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
        if (desc.getType() != getDescriptor()) {
          throw new java.lang.IllegalArgumentException(
            "EnumValueDescriptor is not for this type.");
        }
        if (desc.getIndex() == -1) {
          return UNRECOGNIZED;
        }
        return VALUES[desc.getIndex()];
      }

      private final int value;

      private PropertyType(int value) {
        this.value = value;
      }

      // @@protoc_insertion_point(enum_scope:food.menu.v1.MenuItemOptionProperty.PropertyType)
    }

    /**
     * <pre>
     * Well-defined values for the option property.
     * </pre>
     *
     * Protobuf enum {@code food.menu.v1.MenuItemOptionProperty.PropertyValue}
     */
    public enum PropertyValue
        implements com.google.protobuf.ProtocolMessageEnum {
      /**
       * <pre>
       * Do not use. The property value is not explicitly specified.
       * </pre>
       *
       * <code>UNKNOWN_PROPERTY_VALUE = 0;</code>
       */
      UNKNOWN_PROPERTY_VALUE(0),
      /**
       * <pre>
       * The MenuItemOption applies only to the left side of a pizza.
       * </pre>
       *
       * <code>PIZZA_SIDE_LEFT = 1;</code>
       */
      PIZZA_SIDE_LEFT(1),
      /**
       * <pre>
       * The MenuItemOption applies only to the right side of a pizza.
       * </pre>
       *
       * <code>PIZZA_SIDE_RIGHT = 2;</code>
       */
      PIZZA_SIDE_RIGHT(2),
      /**
       * <pre>
       * The MenuItemOption applies to the entire pizza.
       * </pre>
       *
       * <code>PIZZA_SIDE_WHOLE = 3;</code>
       */
      PIZZA_SIDE_WHOLE(3),
      UNRECOGNIZED(-1),
      ;

      /**
       * <pre>
       * Do not use. The property value is not explicitly specified.
       * </pre>
       *
       * <code>UNKNOWN_PROPERTY_VALUE = 0;</code>
       */
      public static final int UNKNOWN_PROPERTY_VALUE_VALUE = 0;
      /**
       * <pre>
       * The MenuItemOption applies only to the left side of a pizza.
       * </pre>
       *
       * <code>PIZZA_SIDE_LEFT = 1;</code>
       */
      public static final int PIZZA_SIDE_LEFT_VALUE = 1;
      /**
       * <pre>
       * The MenuItemOption applies only to the right side of a pizza.
       * </pre>
       *
       * <code>PIZZA_SIDE_RIGHT = 2;</code>
       */
      public static final int PIZZA_SIDE_RIGHT_VALUE = 2;
      /**
       * <pre>
       * The MenuItemOption applies to the entire pizza.
       * </pre>
       *
       * <code>PIZZA_SIDE_WHOLE = 3;</code>
       */
      public static final int PIZZA_SIDE_WHOLE_VALUE = 3;


      public final int getNumber() {
        if (this == UNRECOGNIZED) {
          throw new java.lang.IllegalArgumentException(
              "Can't get the number of an unknown enum value.");
        }
        return value;
      }

      /**
       * @param value The numeric wire value of the corresponding enum entry.
       * @return The enum associated with the given numeric wire value.
       * @deprecated Use {@link #forNumber(int)} instead.
       */
      @java.lang.Deprecated
      public static PropertyValue valueOf(int value) {
        return forNumber(value);
      }

      /**
       * @param value The numeric wire value of the corresponding enum entry.
       * @return The enum associated with the given numeric wire value.
       */
      public static PropertyValue forNumber(int value) {
        switch (value) {
          case 0: return UNKNOWN_PROPERTY_VALUE;
          case 1: return PIZZA_SIDE_LEFT;
          case 2: return PIZZA_SIDE_RIGHT;
          case 3: return PIZZA_SIDE_WHOLE;
          default: return null;
        }
      }

      public static com.google.protobuf.Internal.EnumLiteMap<PropertyValue>
          internalGetValueMap() {
        return internalValueMap;
      }
      private static final com.google.protobuf.Internal.EnumLiteMap<
          PropertyValue> internalValueMap =
            new com.google.protobuf.Internal.EnumLiteMap<PropertyValue>() {
              public PropertyValue findValueByNumber(int number) {
                return PropertyValue.forNumber(number);
              }
            };

      public final com.google.protobuf.Descriptors.EnumValueDescriptor
          getValueDescriptor() {
        if (this == UNRECOGNIZED) {
          throw new java.lang.IllegalStateException(
              "Can't get the descriptor of an unrecognized enum value.");
        }
        return getDescriptor().getValues().get(ordinal());
      }
      public final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptorForType() {
        return getDescriptor();
      }
      public static final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.MenuItemOptionProperty.getDescriptor().getEnumTypes().get(1);
      }

      private static final PropertyValue[] VALUES = values();

      public static PropertyValue valueOf(
          com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
        if (desc.getType() != getDescriptor()) {
          throw new java.lang.IllegalArgumentException(
            "EnumValueDescriptor is not for this type.");
        }
        if (desc.getIndex() == -1) {
          return UNRECOGNIZED;
        }
        return VALUES[desc.getIndex()];
      }

      private final int value;

      private PropertyValue(int value) {
        this.value = value;
      }

      // @@protoc_insertion_point(enum_scope:food.menu.v1.MenuItemOptionProperty.PropertyValue)
    }

    private int valueCase_ = 0;
    @SuppressWarnings("serial")
    private java.lang.Object value_;
    public enum ValueCase
        implements com.google.protobuf.Internal.EnumLite,
            com.google.protobuf.AbstractMessage.InternalOneOfEnum {
      PROPERTY_VAL(2),
      TEXT_VAL(3),
      VALUE_NOT_SET(0);
      private final int value;
      private ValueCase(int value) {
        this.value = value;
      }
      /**
       * @param value The number of the enum to look for.
       * @return The enum associated with the given number.
       * @deprecated Use {@link #forNumber(int)} instead.
       */
      @java.lang.Deprecated
      public static ValueCase valueOf(int value) {
        return forNumber(value);
      }

      public static ValueCase forNumber(int value) {
        switch (value) {
          case 2: return PROPERTY_VAL;
          case 3: return TEXT_VAL;
          case 0: return VALUE_NOT_SET;
          default: return null;
        }
      }
      public int getNumber() {
        return this.value;
      }
    };

    public ValueCase
    getValueCase() {
      return ValueCase.forNumber(
          valueCase_);
    }

    public static final int PROPERTY_TYPE_FIELD_NUMBER = 1;
    private int propertyType_ = 0;
    /**
     * <pre>
     * The type of this option property.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty.PropertyType property_type = 1;</code>
     * @return The enum numeric value on the wire for propertyType.
     */
    @java.lang.Override public int getPropertyTypeValue() {
      return propertyType_;
    }
    /**
     * <pre>
     * The type of this option property.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty.PropertyType property_type = 1;</code>
     * @return The propertyType.
     */
    @java.lang.Override public food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyType getPropertyType() {
      food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyType result = food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyType.forNumber(propertyType_);
      return result == null ? food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyType.UNRECOGNIZED : result;
    }

    public static final int PROPERTY_VAL_FIELD_NUMBER = 2;
    /**
     * <pre>
     * A well-defined value for the option property. Currently only expected
     * if the property_type is PIZZA_SIDE.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty.PropertyValue property_val = 2;</code>
     * @return Whether the propertyVal field is set.
     */
    public boolean hasPropertyVal() {
      return valueCase_ == 2;
    }
    /**
     * <pre>
     * A well-defined value for the option property. Currently only expected
     * if the property_type is PIZZA_SIDE.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty.PropertyValue property_val = 2;</code>
     * @return The enum numeric value on the wire for propertyVal.
     */
    public int getPropertyValValue() {
      if (valueCase_ == 2) {
        return (java.lang.Integer) value_;
      }
      return 0;
    }
    /**
     * <pre>
     * A well-defined value for the option property. Currently only expected
     * if the property_type is PIZZA_SIDE.
     * </pre>
     *
     * <code>.food.menu.v1.MenuItemOptionProperty.PropertyValue property_val = 2;</code>
     * @return The propertyVal.
     */
    public food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyValue getPropertyVal() {
      if (valueCase_ == 2) {
        food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyValue result = food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyValue.forNumber(
            (java.lang.Integer) value_);
        return result == null ? food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyValue.UNRECOGNIZED : result;
      }
      return food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyValue.UNKNOWN_PROPERTY_VALUE;
    }

    public static final int TEXT_VAL_FIELD_NUMBER = 3;
    /**
     * <pre>
     * A free-form text for the value of the property. Expected for
     * property_type OPTION and SIZE.
     * </pre>
     *
     * <code>.food.menu.v1.TextField text_val = 3;</code>
     * @return Whether the textVal field is set.
     */
    @java.lang.Override
    public boolean hasTextVal() {
      return valueCase_ == 3;
    }
    /**
     * <pre>
     * A free-form text for the value of the property. Expected for
     * property_type OPTION and SIZE.
     * </pre>
     *
     * <code>.food.menu.v1.TextField text_val = 3;</code>
     * @return The textVal.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextField getTextVal() {
      if (valueCase_ == 3) {
         return (food.menu.v1.FoodMenu.TextField) value_;
      }
      return food.menu.v1.FoodMenu.TextField.getDefaultInstance();
    }
    /**
     * <pre>
     * A free-form text for the value of the property. Expected for
     * property_type OPTION and SIZE.
     * </pre>
     *
     * <code>.food.menu.v1.TextField text_val = 3;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextFieldOrBuilder getTextValOrBuilder() {
      if (valueCase_ == 3) {
         return (food.menu.v1.FoodMenu.TextField) value_;
      }
      return food.menu.v1.FoodMenu.TextField.getDefaultInstance();
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (propertyType_ != food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyType.UNKNOWN_PROPERTY_TYPE.getNumber()) {
        output.writeEnum(1, propertyType_);
      }
      if (valueCase_ == 2) {
        output.writeEnum(2, ((java.lang.Integer) value_));
      }
      if (valueCase_ == 3) {
        output.writeMessage(3, (food.menu.v1.FoodMenu.TextField) value_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (propertyType_ != food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyType.UNKNOWN_PROPERTY_TYPE.getNumber()) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, propertyType_);
      }
      if (valueCase_ == 2) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(2, ((java.lang.Integer) value_));
      }
      if (valueCase_ == 3) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, (food.menu.v1.FoodMenu.TextField) value_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.MenuItemOptionProperty)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.MenuItemOptionProperty other = (food.menu.v1.FoodMenu.MenuItemOptionProperty) obj;

      if (propertyType_ != other.propertyType_) return false;
      if (!getValueCase().equals(other.getValueCase())) return false;
      switch (valueCase_) {
        case 2:
          if (getPropertyValValue()
              != other.getPropertyValValue()) return false;
          break;
        case 3:
          if (!getTextVal()
              .equals(other.getTextVal())) return false;
          break;
        case 0:
        default:
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      hash = (37 * hash) + PROPERTY_TYPE_FIELD_NUMBER;
      hash = (53 * hash) + propertyType_;
      switch (valueCase_) {
        case 2:
          hash = (37 * hash) + PROPERTY_VAL_FIELD_NUMBER;
          hash = (53 * hash) + getPropertyValValue();
          break;
        case 3:
          hash = (37 * hash) + TEXT_VAL_FIELD_NUMBER;
          hash = (53 * hash) + getTextVal().hashCode();
          break;
        case 0:
        default:
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.MenuItemOptionProperty parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuItemOptionProperty parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemOptionProperty parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuItemOptionProperty parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemOptionProperty parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.MenuItemOptionProperty parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemOptionProperty parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuItemOptionProperty parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemOptionProperty parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuItemOptionProperty parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.MenuItemOptionProperty parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.MenuItemOptionProperty parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.MenuItemOptionProperty prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Describes the property of a menu item option and its value.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.MenuItemOptionProperty}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.MenuItemOptionProperty)
        food.menu.v1.FoodMenu.MenuItemOptionPropertyOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemOptionProperty_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemOptionProperty_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.MenuItemOptionProperty.class, food.menu.v1.FoodMenu.MenuItemOptionProperty.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.MenuItemOptionProperty.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        propertyType_ = 0;
        if (textValBuilder_ != null) {
          textValBuilder_.clear();
        }
        valueCase_ = 0;
        value_ = null;
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_MenuItemOptionProperty_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemOptionProperty getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.MenuItemOptionProperty.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemOptionProperty build() {
        food.menu.v1.FoodMenu.MenuItemOptionProperty result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemOptionProperty buildPartial() {
        food.menu.v1.FoodMenu.MenuItemOptionProperty result = new food.menu.v1.FoodMenu.MenuItemOptionProperty(this);
        if (bitField0_ != 0) { buildPartial0(result); }
        buildPartialOneofs(result);
        onBuilt();
        return result;
      }

      private void buildPartial0(food.menu.v1.FoodMenu.MenuItemOptionProperty result) {
        int from_bitField0_ = bitField0_;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.propertyType_ = propertyType_;
        }
      }

      private void buildPartialOneofs(food.menu.v1.FoodMenu.MenuItemOptionProperty result) {
        result.valueCase_ = valueCase_;
        result.value_ = this.value_;
        if (valueCase_ == 3 &&
            textValBuilder_ != null) {
          result.value_ = textValBuilder_.build();
        }
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.MenuItemOptionProperty) {
          return mergeFrom((food.menu.v1.FoodMenu.MenuItemOptionProperty)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.MenuItemOptionProperty other) {
        if (other == food.menu.v1.FoodMenu.MenuItemOptionProperty.getDefaultInstance()) return this;
        if (other.propertyType_ != 0) {
          setPropertyTypeValue(other.getPropertyTypeValue());
        }
        switch (other.getValueCase()) {
          case PROPERTY_VAL: {
            setPropertyValValue(other.getPropertyValValue());
            break;
          }
          case TEXT_VAL: {
            mergeTextVal(other.getTextVal());
            break;
          }
          case VALUE_NOT_SET: {
            break;
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                propertyType_ = input.readEnum();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 16: {
                int rawValue = input.readEnum();
                valueCase_ = 2;
                value_ = rawValue;
                break;
              } // case 16
              case 26: {
                input.readMessage(
                    getTextValFieldBuilder().getBuilder(),
                    extensionRegistry);
                valueCase_ = 3;
                break;
              } // case 26
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int valueCase_ = 0;
      private java.lang.Object value_;
      public ValueCase
          getValueCase() {
        return ValueCase.forNumber(
            valueCase_);
      }

      public Builder clearValue() {
        valueCase_ = 0;
        value_ = null;
        onChanged();
        return this;
      }

      private int bitField0_;

      private int propertyType_ = 0;
      /**
       * <pre>
       * The type of this option property.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty.PropertyType property_type = 1;</code>
       * @return The enum numeric value on the wire for propertyType.
       */
      @java.lang.Override public int getPropertyTypeValue() {
        return propertyType_;
      }
      /**
       * <pre>
       * The type of this option property.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty.PropertyType property_type = 1;</code>
       * @param value The enum numeric value on the wire for propertyType to set.
       * @return This builder for chaining.
       */
      public Builder setPropertyTypeValue(int value) {
        propertyType_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The type of this option property.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty.PropertyType property_type = 1;</code>
       * @return The propertyType.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyType getPropertyType() {
        food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyType result = food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyType.forNumber(propertyType_);
        return result == null ? food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyType.UNRECOGNIZED : result;
      }
      /**
       * <pre>
       * The type of this option property.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty.PropertyType property_type = 1;</code>
       * @param value The propertyType to set.
       * @return This builder for chaining.
       */
      public Builder setPropertyType(food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        propertyType_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The type of this option property.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty.PropertyType property_type = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearPropertyType() {
        bitField0_ = (bitField0_ & ~0x00000001);
        propertyType_ = 0;
        onChanged();
        return this;
      }

      /**
       * <pre>
       * A well-defined value for the option property. Currently only expected
       * if the property_type is PIZZA_SIDE.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty.PropertyValue property_val = 2;</code>
       * @return Whether the propertyVal field is set.
       */
      @java.lang.Override
      public boolean hasPropertyVal() {
        return valueCase_ == 2;
      }
      /**
       * <pre>
       * A well-defined value for the option property. Currently only expected
       * if the property_type is PIZZA_SIDE.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty.PropertyValue property_val = 2;</code>
       * @return The enum numeric value on the wire for propertyVal.
       */
      @java.lang.Override
      public int getPropertyValValue() {
        if (valueCase_ == 2) {
          return ((java.lang.Integer) value_).intValue();
        }
        return 0;
      }
      /**
       * <pre>
       * A well-defined value for the option property. Currently only expected
       * if the property_type is PIZZA_SIDE.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty.PropertyValue property_val = 2;</code>
       * @param value The enum numeric value on the wire for propertyVal to set.
       * @return This builder for chaining.
       */
      public Builder setPropertyValValue(int value) {
        valueCase_ = 2;
        value_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * A well-defined value for the option property. Currently only expected
       * if the property_type is PIZZA_SIDE.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty.PropertyValue property_val = 2;</code>
       * @return The propertyVal.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyValue getPropertyVal() {
        if (valueCase_ == 2) {
          food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyValue result = food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyValue.forNumber(
              (java.lang.Integer) value_);
          return result == null ? food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyValue.UNRECOGNIZED : result;
        }
        return food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyValue.UNKNOWN_PROPERTY_VALUE;
      }
      /**
       * <pre>
       * A well-defined value for the option property. Currently only expected
       * if the property_type is PIZZA_SIDE.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty.PropertyValue property_val = 2;</code>
       * @param value The propertyVal to set.
       * @return This builder for chaining.
       */
      public Builder setPropertyVal(food.menu.v1.FoodMenu.MenuItemOptionProperty.PropertyValue value) {
        if (value == null) {
          throw new NullPointerException();
        }
        valueCase_ = 2;
        value_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * A well-defined value for the option property. Currently only expected
       * if the property_type is PIZZA_SIDE.
       * </pre>
       *
       * <code>.food.menu.v1.MenuItemOptionProperty.PropertyValue property_val = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearPropertyVal() {
        if (valueCase_ == 2) {
          valueCase_ = 0;
          value_ = null;
          onChanged();
        }
        return this;
      }

      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> textValBuilder_;
      /**
       * <pre>
       * A free-form text for the value of the property. Expected for
       * property_type OPTION and SIZE.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text_val = 3;</code>
       * @return Whether the textVal field is set.
       */
      @java.lang.Override
      public boolean hasTextVal() {
        return valueCase_ == 3;
      }
      /**
       * <pre>
       * A free-form text for the value of the property. Expected for
       * property_type OPTION and SIZE.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text_val = 3;</code>
       * @return The textVal.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.TextField getTextVal() {
        if (textValBuilder_ == null) {
          if (valueCase_ == 3) {
            return (food.menu.v1.FoodMenu.TextField) value_;
          }
          return food.menu.v1.FoodMenu.TextField.getDefaultInstance();
        } else {
          if (valueCase_ == 3) {
            return textValBuilder_.getMessage();
          }
          return food.menu.v1.FoodMenu.TextField.getDefaultInstance();
        }
      }
      /**
       * <pre>
       * A free-form text for the value of the property. Expected for
       * property_type OPTION and SIZE.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text_val = 3;</code>
       */
      public Builder setTextVal(food.menu.v1.FoodMenu.TextField value) {
        if (textValBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          value_ = value;
          onChanged();
        } else {
          textValBuilder_.setMessage(value);
        }
        valueCase_ = 3;
        return this;
      }
      /**
       * <pre>
       * A free-form text for the value of the property. Expected for
       * property_type OPTION and SIZE.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text_val = 3;</code>
       */
      public Builder setTextVal(
          food.menu.v1.FoodMenu.TextField.Builder builderForValue) {
        if (textValBuilder_ == null) {
          value_ = builderForValue.build();
          onChanged();
        } else {
          textValBuilder_.setMessage(builderForValue.build());
        }
        valueCase_ = 3;
        return this;
      }
      /**
       * <pre>
       * A free-form text for the value of the property. Expected for
       * property_type OPTION and SIZE.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text_val = 3;</code>
       */
      public Builder mergeTextVal(food.menu.v1.FoodMenu.TextField value) {
        if (textValBuilder_ == null) {
          if (valueCase_ == 3 &&
              value_ != food.menu.v1.FoodMenu.TextField.getDefaultInstance()) {
            value_ = food.menu.v1.FoodMenu.TextField.newBuilder((food.menu.v1.FoodMenu.TextField) value_)
                .mergeFrom(value).buildPartial();
          } else {
            value_ = value;
          }
          onChanged();
        } else {
          if (valueCase_ == 3) {
            textValBuilder_.mergeFrom(value);
          } else {
            textValBuilder_.setMessage(value);
          }
        }
        valueCase_ = 3;
        return this;
      }
      /**
       * <pre>
       * A free-form text for the value of the property. Expected for
       * property_type OPTION and SIZE.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text_val = 3;</code>
       */
      public Builder clearTextVal() {
        if (textValBuilder_ == null) {
          if (valueCase_ == 3) {
            valueCase_ = 0;
            value_ = null;
            onChanged();
          }
        } else {
          if (valueCase_ == 3) {
            valueCase_ = 0;
            value_ = null;
          }
          textValBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       * A free-form text for the value of the property. Expected for
       * property_type OPTION and SIZE.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text_val = 3;</code>
       */
      public food.menu.v1.FoodMenu.TextField.Builder getTextValBuilder() {
        return getTextValFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * A free-form text for the value of the property. Expected for
       * property_type OPTION and SIZE.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text_val = 3;</code>
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.TextFieldOrBuilder getTextValOrBuilder() {
        if ((valueCase_ == 3) && (textValBuilder_ != null)) {
          return textValBuilder_.getMessageOrBuilder();
        } else {
          if (valueCase_ == 3) {
            return (food.menu.v1.FoodMenu.TextField) value_;
          }
          return food.menu.v1.FoodMenu.TextField.getDefaultInstance();
        }
      }
      /**
       * <pre>
       * A free-form text for the value of the property. Expected for
       * property_type OPTION and SIZE.
       * </pre>
       *
       * <code>.food.menu.v1.TextField text_val = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> 
          getTextValFieldBuilder() {
        if (textValBuilder_ == null) {
          if (!(valueCase_ == 3)) {
            value_ = food.menu.v1.FoodMenu.TextField.getDefaultInstance();
          }
          textValBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder>(
                  (food.menu.v1.FoodMenu.TextField) value_,
                  getParentForChildren(),
                  isClean());
          value_ = null;
        }
        valueCase_ = 3;
        onChanged();
        return textValBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.MenuItemOptionProperty)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.MenuItemOptionProperty)
    private static final food.menu.v1.FoodMenu.MenuItemOptionProperty DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.MenuItemOptionProperty();
    }

    public static food.menu.v1.FoodMenu.MenuItemOptionProperty getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<MenuItemOptionProperty>
        PARSER = new com.google.protobuf.AbstractParser<MenuItemOptionProperty>() {
      @java.lang.Override
      public MenuItemOptionProperty parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<MenuItemOptionProperty> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<MenuItemOptionProperty> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.MenuItemOptionProperty getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface NutritionInformationOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.NutritionInformation)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * The amount of nutritional energy of the serving of food. Can be defined
     * in Calories or kilojoules.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
     * @return Whether the energy field is set.
     */
    boolean hasEnergy();
    /**
     * <pre>
     * The amount of nutritional energy of the serving of food. Can be defined
     * in Calories or kilojoules.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
     * @return The energy.
     */
    food.menu.v1.FoodMenu.NutritionInformation.NutritionValue getEnergy();
    /**
     * <pre>
     * The amount of nutritional energy of the serving of food. Can be defined
     * in Calories or kilojoules.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
     */
    food.menu.v1.FoodMenu.NutritionInformation.NutritionValueOrBuilder getEnergyOrBuilder();

    /**
     * <pre>
     * The amount of sodium content, measured in grams or milligrams.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
     * @return Whether the sodiumContent field is set.
     */
    boolean hasSodiumContent();
    /**
     * <pre>
     * The amount of sodium content, measured in grams or milligrams.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
     * @return The sodiumContent.
     */
    food.menu.v1.FoodMenu.NutritionInformation.NutritionValue getSodiumContent();
    /**
     * <pre>
     * The amount of sodium content, measured in grams or milligrams.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
     */
    food.menu.v1.FoodMenu.NutritionInformation.NutritionValueOrBuilder getSodiumContentOrBuilder();

    /**
     * <pre>
     * The number of servings the nutrition value applies to.
     * Optional.
     * </pre>
     *
     * <code>optional int32 serving_size = 3;</code>
     * @return Whether the servingSize field is set.
     */
    boolean hasServingSize();
    /**
     * <pre>
     * The number of servings the nutrition value applies to.
     * Optional.
     * </pre>
     *
     * <code>optional int32 serving_size = 3;</code>
     * @return The servingSize.
     */
    int getServingSize();

    /**
     * <pre>
     * Nutrition information in free text. For example "Contains preservatives".
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 4;</code>
     * @return Whether the description field is set.
     */
    boolean hasDescription();
    /**
     * <pre>
     * Nutrition information in free text. For example "Contains preservatives".
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 4;</code>
     * @return The description.
     */
    food.menu.v1.FoodMenu.TextField getDescription();
    /**
     * <pre>
     * Nutrition information in free text. For example "Contains preservatives".
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 4;</code>
     */
    food.menu.v1.FoodMenu.TextFieldOrBuilder getDescriptionOrBuilder();
  }
  /**
   * <pre>
   * Describes all the nutritional measurements of a MenuItem or add-on.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.NutritionInformation}
   */
  public static final class NutritionInformation extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.NutritionInformation)
      NutritionInformationOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use NutritionInformation.newBuilder() to construct.
    private NutritionInformation(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private NutritionInformation() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new NutritionInformation();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.NutritionInformation.class, food.menu.v1.FoodMenu.NutritionInformation.Builder.class);
    }

    public interface NutritionValueOrBuilder extends
        // @@protoc_insertion_point(interface_extends:food.menu.v1.NutritionInformation.NutritionValue)
        com.google.protobuf.MessageOrBuilder {

      /**
       * <pre>
       * A single number representing the amount of nutritional value.
       * </pre>
       *
       * <code>double amount = 1;</code>
       * @return Whether the amount field is set.
       */
      boolean hasAmount();
      /**
       * <pre>
       * A single number representing the amount of nutritional value.
       * </pre>
       *
       * <code>double amount = 1;</code>
       * @return The amount.
       */
      double getAmount();

      /**
       * <pre>
       * A range representing the amount of nutritional value.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
       * @return Whether the range field is set.
       */
      boolean hasRange();
      /**
       * <pre>
       * A range representing the amount of nutritional value.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
       * @return The range.
       */
      food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range getRange();
      /**
       * <pre>
       * A range representing the amount of nutritional value.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
       */
      food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.RangeOrBuilder getRangeOrBuilder();

      /**
       * <pre>
       * The unit associated with the amount as specified from the partner. We
       * will validate the feed so that the unit for each type of nutrition value
       * is expected for that type of value. For example, only ENERGY_CALORIES
       * and ENERGY_KILOJOULES are expected on energy property of
       * NutritionalInformation.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionValueUnit unit = 2;</code>
       * @return The enum numeric value on the wire for unit.
       */
      int getUnitValue();
      /**
       * <pre>
       * The unit associated with the amount as specified from the partner. We
       * will validate the feed so that the unit for each type of nutrition value
       * is expected for that type of value. For example, only ENERGY_CALORIES
       * and ENERGY_KILOJOULES are expected on energy property of
       * NutritionalInformation.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionValueUnit unit = 2;</code>
       * @return The unit.
       */
      food.menu.v1.FoodMenu.NutritionValueUnit getUnit();

      food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.ValueCase getValueCase();
    }
    /**
     * <pre>
     * Describes a single nutritional measurement of the serving of food.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.NutritionInformation.NutritionValue}
     */
    public static final class NutritionValue extends
        com.google.protobuf.GeneratedMessageV3 implements
        // @@protoc_insertion_point(message_implements:food.menu.v1.NutritionInformation.NutritionValue)
        NutritionValueOrBuilder {
    private static final long serialVersionUID = 0L;
      // Use NutritionValue.newBuilder() to construct.
      private NutritionValue(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
        super(builder);
      }
      private NutritionValue() {
        unit_ = 0;
      }

      @java.lang.Override
      @SuppressWarnings({"unused"})
      protected java.lang.Object newInstance(
          UnusedPrivateParameter unused) {
        return new NutritionValue();
      }

      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_NutritionValue_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_NutritionValue_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.class, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Builder.class);
      }

      public interface RangeOrBuilder extends
          // @@protoc_insertion_point(interface_extends:food.menu.v1.NutritionInformation.NutritionValue.Range)
          com.google.protobuf.MessageOrBuilder {

        /**
         * <pre>
         * The minimum amount of nutrition value.
         * Required.
         * </pre>
         *
         * <code>double min = 1;</code>
         * @return The min.
         */
        double getMin();

        /**
         * <pre>
         * The maximum amount of nutrition value.
         * Required.
         * </pre>
         *
         * <code>double max = 2;</code>
         * @return The max.
         */
        double getMax();
      }
      /**
       * <pre>
       * Describes a closed range for the nutrition value. E.g. "100-150 cal"
       * </pre>
       *
       * Protobuf type {@code food.menu.v1.NutritionInformation.NutritionValue.Range}
       */
      public static final class Range extends
          com.google.protobuf.GeneratedMessageV3 implements
          // @@protoc_insertion_point(message_implements:food.menu.v1.NutritionInformation.NutritionValue.Range)
          RangeOrBuilder {
      private static final long serialVersionUID = 0L;
        // Use Range.newBuilder() to construct.
        private Range(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
          super(builder);
        }
        private Range() {
        }

        @java.lang.Override
        @SuppressWarnings({"unused"})
        protected java.lang.Object newInstance(
            UnusedPrivateParameter unused) {
          return new Range();
        }

        public static final com.google.protobuf.Descriptors.Descriptor
            getDescriptor() {
          return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_NutritionValue_Range_descriptor;
        }

        @java.lang.Override
        protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
            internalGetFieldAccessorTable() {
          return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_NutritionValue_Range_fieldAccessorTable
              .ensureFieldAccessorsInitialized(
                  food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.class, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.Builder.class);
        }

        public static final int MIN_FIELD_NUMBER = 1;
        private double min_ = 0D;
        /**
         * <pre>
         * The minimum amount of nutrition value.
         * Required.
         * </pre>
         *
         * <code>double min = 1;</code>
         * @return The min.
         */
        @java.lang.Override
        public double getMin() {
          return min_;
        }

        public static final int MAX_FIELD_NUMBER = 2;
        private double max_ = 0D;
        /**
         * <pre>
         * The maximum amount of nutrition value.
         * Required.
         * </pre>
         *
         * <code>double max = 2;</code>
         * @return The max.
         */
        @java.lang.Override
        public double getMax() {
          return max_;
        }

        private byte memoizedIsInitialized = -1;
        @java.lang.Override
        public final boolean isInitialized() {
          byte isInitialized = memoizedIsInitialized;
          if (isInitialized == 1) return true;
          if (isInitialized == 0) return false;

          memoizedIsInitialized = 1;
          return true;
        }

        @java.lang.Override
        public void writeTo(com.google.protobuf.CodedOutputStream output)
                            throws java.io.IOException {
          if (java.lang.Double.doubleToRawLongBits(min_) != 0) {
            output.writeDouble(1, min_);
          }
          if (java.lang.Double.doubleToRawLongBits(max_) != 0) {
            output.writeDouble(2, max_);
          }
          getUnknownFields().writeTo(output);
        }

        @java.lang.Override
        public int getSerializedSize() {
          int size = memoizedSize;
          if (size != -1) return size;

          size = 0;
          if (java.lang.Double.doubleToRawLongBits(min_) != 0) {
            size += com.google.protobuf.CodedOutputStream
              .computeDoubleSize(1, min_);
          }
          if (java.lang.Double.doubleToRawLongBits(max_) != 0) {
            size += com.google.protobuf.CodedOutputStream
              .computeDoubleSize(2, max_);
          }
          size += getUnknownFields().getSerializedSize();
          memoizedSize = size;
          return size;
        }

        @java.lang.Override
        public boolean equals(final java.lang.Object obj) {
          if (obj == this) {
           return true;
          }
          if (!(obj instanceof food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range)) {
            return super.equals(obj);
          }
          food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range other = (food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range) obj;

          if (java.lang.Double.doubleToLongBits(getMin())
              != java.lang.Double.doubleToLongBits(
                  other.getMin())) return false;
          if (java.lang.Double.doubleToLongBits(getMax())
              != java.lang.Double.doubleToLongBits(
                  other.getMax())) return false;
          if (!getUnknownFields().equals(other.getUnknownFields())) return false;
          return true;
        }

        @java.lang.Override
        public int hashCode() {
          if (memoizedHashCode != 0) {
            return memoizedHashCode;
          }
          int hash = 41;
          hash = (19 * hash) + getDescriptor().hashCode();
          hash = (37 * hash) + MIN_FIELD_NUMBER;
          hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
              java.lang.Double.doubleToLongBits(getMin()));
          hash = (37 * hash) + MAX_FIELD_NUMBER;
          hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
              java.lang.Double.doubleToLongBits(getMax()));
          hash = (29 * hash) + getUnknownFields().hashCode();
          memoizedHashCode = hash;
          return hash;
        }

        public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range parseFrom(
            java.nio.ByteBuffer data)
            throws com.google.protobuf.InvalidProtocolBufferException {
          return PARSER.parseFrom(data);
        }
        public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range parseFrom(
            java.nio.ByteBuffer data,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws com.google.protobuf.InvalidProtocolBufferException {
          return PARSER.parseFrom(data, extensionRegistry);
        }
        public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range parseFrom(
            com.google.protobuf.ByteString data)
            throws com.google.protobuf.InvalidProtocolBufferException {
          return PARSER.parseFrom(data);
        }
        public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range parseFrom(
            com.google.protobuf.ByteString data,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws com.google.protobuf.InvalidProtocolBufferException {
          return PARSER.parseFrom(data, extensionRegistry);
        }
        public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range parseFrom(byte[] data)
            throws com.google.protobuf.InvalidProtocolBufferException {
          return PARSER.parseFrom(data);
        }
        public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range parseFrom(
            byte[] data,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws com.google.protobuf.InvalidProtocolBufferException {
          return PARSER.parseFrom(data, extensionRegistry);
        }
        public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range parseFrom(java.io.InputStream input)
            throws java.io.IOException {
          return com.google.protobuf.GeneratedMessageV3
              .parseWithIOException(PARSER, input);
        }
        public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range parseFrom(
            java.io.InputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws java.io.IOException {
          return com.google.protobuf.GeneratedMessageV3
              .parseWithIOException(PARSER, input, extensionRegistry);
        }
        public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range parseDelimitedFrom(java.io.InputStream input)
            throws java.io.IOException {
          return com.google.protobuf.GeneratedMessageV3
              .parseDelimitedWithIOException(PARSER, input);
        }
        public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range parseDelimitedFrom(
            java.io.InputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws java.io.IOException {
          return com.google.protobuf.GeneratedMessageV3
              .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
        }
        public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range parseFrom(
            com.google.protobuf.CodedInputStream input)
            throws java.io.IOException {
          return com.google.protobuf.GeneratedMessageV3
              .parseWithIOException(PARSER, input);
        }
        public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range parseFrom(
            com.google.protobuf.CodedInputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws java.io.IOException {
          return com.google.protobuf.GeneratedMessageV3
              .parseWithIOException(PARSER, input, extensionRegistry);
        }

        @java.lang.Override
        public Builder newBuilderForType() { return newBuilder(); }
        public static Builder newBuilder() {
          return DEFAULT_INSTANCE.toBuilder();
        }
        public static Builder newBuilder(food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range prototype) {
          return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
        }
        @java.lang.Override
        public Builder toBuilder() {
          return this == DEFAULT_INSTANCE
              ? new Builder() : new Builder().mergeFrom(this);
        }

        @java.lang.Override
        protected Builder newBuilderForType(
            com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
          Builder builder = new Builder(parent);
          return builder;
        }
        /**
         * <pre>
         * Describes a closed range for the nutrition value. E.g. "100-150 cal"
         * </pre>
         *
         * Protobuf type {@code food.menu.v1.NutritionInformation.NutritionValue.Range}
         */
        public static final class Builder extends
            com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
            // @@protoc_insertion_point(builder_implements:food.menu.v1.NutritionInformation.NutritionValue.Range)
            food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.RangeOrBuilder {
          public static final com.google.protobuf.Descriptors.Descriptor
              getDescriptor() {
            return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_NutritionValue_Range_descriptor;
          }

          @java.lang.Override
          protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
              internalGetFieldAccessorTable() {
            return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_NutritionValue_Range_fieldAccessorTable
                .ensureFieldAccessorsInitialized(
                    food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.class, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.Builder.class);
          }

          // Construct using food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.newBuilder()
          private Builder() {

          }

          private Builder(
              com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
            super(parent);

          }
          @java.lang.Override
          public Builder clear() {
            super.clear();
            bitField0_ = 0;
            min_ = 0D;
            max_ = 0D;
            return this;
          }

          @java.lang.Override
          public com.google.protobuf.Descriptors.Descriptor
              getDescriptorForType() {
            return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_NutritionValue_Range_descriptor;
          }

          @java.lang.Override
          public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range getDefaultInstanceForType() {
            return food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.getDefaultInstance();
          }

          @java.lang.Override
          public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range build() {
            food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range result = buildPartial();
            if (!result.isInitialized()) {
              throw newUninitializedMessageException(result);
            }
            return result;
          }

          @java.lang.Override
          public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range buildPartial() {
            food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range result = new food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range(this);
            if (bitField0_ != 0) { buildPartial0(result); }
            onBuilt();
            return result;
          }

          private void buildPartial0(food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range result) {
            int from_bitField0_ = bitField0_;
            if (((from_bitField0_ & 0x00000001) != 0)) {
              result.min_ = min_;
            }
            if (((from_bitField0_ & 0x00000002) != 0)) {
              result.max_ = max_;
            }
          }

          @java.lang.Override
          public Builder mergeFrom(com.google.protobuf.Message other) {
            if (other instanceof food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range) {
              return mergeFrom((food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range)other);
            } else {
              super.mergeFrom(other);
              return this;
            }
          }

          public Builder mergeFrom(food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range other) {
            if (other == food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.getDefaultInstance()) return this;
            if (other.getMin() != 0D) {
              setMin(other.getMin());
            }
            if (other.getMax() != 0D) {
              setMax(other.getMax());
            }
            this.mergeUnknownFields(other.getUnknownFields());
            onChanged();
            return this;
          }

          @java.lang.Override
          public final boolean isInitialized() {
            return true;
          }

          @java.lang.Override
          public Builder mergeFrom(
              com.google.protobuf.CodedInputStream input,
              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
              throws java.io.IOException {
            if (extensionRegistry == null) {
              throw new java.lang.NullPointerException();
            }
            try {
              boolean done = false;
              while (!done) {
                int tag = input.readTag();
                switch (tag) {
                  case 0:
                    done = true;
                    break;
                  case 9: {
                    min_ = input.readDouble();
                    bitField0_ |= 0x00000001;
                    break;
                  } // case 9
                  case 17: {
                    max_ = input.readDouble();
                    bitField0_ |= 0x00000002;
                    break;
                  } // case 17
                  default: {
                    if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                      done = true; // was an endgroup tag
                    }
                    break;
                  } // default:
                } // switch (tag)
              } // while (!done)
            } catch (com.google.protobuf.InvalidProtocolBufferException e) {
              throw e.unwrapIOException();
            } finally {
              onChanged();
            } // finally
            return this;
          }
          private int bitField0_;

          private double min_ ;
          /**
           * <pre>
           * The minimum amount of nutrition value.
           * Required.
           * </pre>
           *
           * <code>double min = 1;</code>
           * @return The min.
           */
          @java.lang.Override
          public double getMin() {
            return min_;
          }
          /**
           * <pre>
           * The minimum amount of nutrition value.
           * Required.
           * </pre>
           *
           * <code>double min = 1;</code>
           * @param value The min to set.
           * @return This builder for chaining.
           */
          public Builder setMin(double value) {

            min_ = value;
            bitField0_ |= 0x00000001;
            onChanged();
            return this;
          }
          /**
           * <pre>
           * The minimum amount of nutrition value.
           * Required.
           * </pre>
           *
           * <code>double min = 1;</code>
           * @return This builder for chaining.
           */
          public Builder clearMin() {
            bitField0_ = (bitField0_ & ~0x00000001);
            min_ = 0D;
            onChanged();
            return this;
          }

          private double max_ ;
          /**
           * <pre>
           * The maximum amount of nutrition value.
           * Required.
           * </pre>
           *
           * <code>double max = 2;</code>
           * @return The max.
           */
          @java.lang.Override
          public double getMax() {
            return max_;
          }
          /**
           * <pre>
           * The maximum amount of nutrition value.
           * Required.
           * </pre>
           *
           * <code>double max = 2;</code>
           * @param value The max to set.
           * @return This builder for chaining.
           */
          public Builder setMax(double value) {

            max_ = value;
            bitField0_ |= 0x00000002;
            onChanged();
            return this;
          }
          /**
           * <pre>
           * The maximum amount of nutrition value.
           * Required.
           * </pre>
           *
           * <code>double max = 2;</code>
           * @return This builder for chaining.
           */
          public Builder clearMax() {
            bitField0_ = (bitField0_ & ~0x00000002);
            max_ = 0D;
            onChanged();
            return this;
          }
          @java.lang.Override
          public final Builder setUnknownFields(
              final com.google.protobuf.UnknownFieldSet unknownFields) {
            return super.setUnknownFields(unknownFields);
          }

          @java.lang.Override
          public final Builder mergeUnknownFields(
              final com.google.protobuf.UnknownFieldSet unknownFields) {
            return super.mergeUnknownFields(unknownFields);
          }


          // @@protoc_insertion_point(builder_scope:food.menu.v1.NutritionInformation.NutritionValue.Range)
        }

        // @@protoc_insertion_point(class_scope:food.menu.v1.NutritionInformation.NutritionValue.Range)
        private static final food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range DEFAULT_INSTANCE;
        static {
          DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range();
        }

        public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range getDefaultInstance() {
          return DEFAULT_INSTANCE;
        }

        private static final com.google.protobuf.Parser<Range>
            PARSER = new com.google.protobuf.AbstractParser<Range>() {
          @java.lang.Override
          public Range parsePartialFrom(
              com.google.protobuf.CodedInputStream input,
              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
              throws com.google.protobuf.InvalidProtocolBufferException {
            Builder builder = newBuilder();
            try {
              builder.mergeFrom(input, extensionRegistry);
            } catch (com.google.protobuf.InvalidProtocolBufferException e) {
              throw e.setUnfinishedMessage(builder.buildPartial());
            } catch (com.google.protobuf.UninitializedMessageException e) {
              throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
            } catch (java.io.IOException e) {
              throw new com.google.protobuf.InvalidProtocolBufferException(e)
                  .setUnfinishedMessage(builder.buildPartial());
            }
            return builder.buildPartial();
          }
        };

        public static com.google.protobuf.Parser<Range> parser() {
          return PARSER;
        }

        @java.lang.Override
        public com.google.protobuf.Parser<Range> getParserForType() {
          return PARSER;
        }

        @java.lang.Override
        public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range getDefaultInstanceForType() {
          return DEFAULT_INSTANCE;
        }

      }

      private int valueCase_ = 0;
      @SuppressWarnings("serial")
      private java.lang.Object value_;
      public enum ValueCase
          implements com.google.protobuf.Internal.EnumLite,
              com.google.protobuf.AbstractMessage.InternalOneOfEnum {
        AMOUNT(1),
        RANGE(3),
        VALUE_NOT_SET(0);
        private final int value;
        private ValueCase(int value) {
          this.value = value;
        }
        /**
         * @param value The number of the enum to look for.
         * @return The enum associated with the given number.
         * @deprecated Use {@link #forNumber(int)} instead.
         */
        @java.lang.Deprecated
        public static ValueCase valueOf(int value) {
          return forNumber(value);
        }

        public static ValueCase forNumber(int value) {
          switch (value) {
            case 1: return AMOUNT;
            case 3: return RANGE;
            case 0: return VALUE_NOT_SET;
            default: return null;
          }
        }
        public int getNumber() {
          return this.value;
        }
      };

      public ValueCase
      getValueCase() {
        return ValueCase.forNumber(
            valueCase_);
      }

      public static final int AMOUNT_FIELD_NUMBER = 1;
      /**
       * <pre>
       * A single number representing the amount of nutritional value.
       * </pre>
       *
       * <code>double amount = 1;</code>
       * @return Whether the amount field is set.
       */
      @java.lang.Override
      public boolean hasAmount() {
        return valueCase_ == 1;
      }
      /**
       * <pre>
       * A single number representing the amount of nutritional value.
       * </pre>
       *
       * <code>double amount = 1;</code>
       * @return The amount.
       */
      @java.lang.Override
      public double getAmount() {
        if (valueCase_ == 1) {
          return (java.lang.Double) value_;
        }
        return 0D;
      }

      public static final int RANGE_FIELD_NUMBER = 3;
      /**
       * <pre>
       * A range representing the amount of nutritional value.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
       * @return Whether the range field is set.
       */
      @java.lang.Override
      public boolean hasRange() {
        return valueCase_ == 3;
      }
      /**
       * <pre>
       * A range representing the amount of nutritional value.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
       * @return The range.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range getRange() {
        if (valueCase_ == 3) {
           return (food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range) value_;
        }
        return food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.getDefaultInstance();
      }
      /**
       * <pre>
       * A range representing the amount of nutritional value.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.RangeOrBuilder getRangeOrBuilder() {
        if (valueCase_ == 3) {
           return (food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range) value_;
        }
        return food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.getDefaultInstance();
      }

      public static final int UNIT_FIELD_NUMBER = 2;
      private int unit_ = 0;
      /**
       * <pre>
       * The unit associated with the amount as specified from the partner. We
       * will validate the feed so that the unit for each type of nutrition value
       * is expected for that type of value. For example, only ENERGY_CALORIES
       * and ENERGY_KILOJOULES are expected on energy property of
       * NutritionalInformation.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionValueUnit unit = 2;</code>
       * @return The enum numeric value on the wire for unit.
       */
      @java.lang.Override public int getUnitValue() {
        return unit_;
      }
      /**
       * <pre>
       * The unit associated with the amount as specified from the partner. We
       * will validate the feed so that the unit for each type of nutrition value
       * is expected for that type of value. For example, only ENERGY_CALORIES
       * and ENERGY_KILOJOULES are expected on energy property of
       * NutritionalInformation.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionValueUnit unit = 2;</code>
       * @return The unit.
       */
      @java.lang.Override public food.menu.v1.FoodMenu.NutritionValueUnit getUnit() {
        food.menu.v1.FoodMenu.NutritionValueUnit result = food.menu.v1.FoodMenu.NutritionValueUnit.forNumber(unit_);
        return result == null ? food.menu.v1.FoodMenu.NutritionValueUnit.UNRECOGNIZED : result;
      }

      private byte memoizedIsInitialized = -1;
      @java.lang.Override
      public final boolean isInitialized() {
        byte isInitialized = memoizedIsInitialized;
        if (isInitialized == 1) return true;
        if (isInitialized == 0) return false;

        memoizedIsInitialized = 1;
        return true;
      }

      @java.lang.Override
      public void writeTo(com.google.protobuf.CodedOutputStream output)
                          throws java.io.IOException {
        if (valueCase_ == 1) {
          output.writeDouble(
              1, (double)((java.lang.Double) value_));
        }
        if (unit_ != food.menu.v1.FoodMenu.NutritionValueUnit.NUTRITION_VALUE_UNIT_UNSPECIFIED.getNumber()) {
          output.writeEnum(2, unit_);
        }
        if (valueCase_ == 3) {
          output.writeMessage(3, (food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range) value_);
        }
        getUnknownFields().writeTo(output);
      }

      @java.lang.Override
      public int getSerializedSize() {
        int size = memoizedSize;
        if (size != -1) return size;

        size = 0;
        if (valueCase_ == 1) {
          size += com.google.protobuf.CodedOutputStream
            .computeDoubleSize(
                1, (double)((java.lang.Double) value_));
        }
        if (unit_ != food.menu.v1.FoodMenu.NutritionValueUnit.NUTRITION_VALUE_UNIT_UNSPECIFIED.getNumber()) {
          size += com.google.protobuf.CodedOutputStream
            .computeEnumSize(2, unit_);
        }
        if (valueCase_ == 3) {
          size += com.google.protobuf.CodedOutputStream
            .computeMessageSize(3, (food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range) value_);
        }
        size += getUnknownFields().getSerializedSize();
        memoizedSize = size;
        return size;
      }

      @java.lang.Override
      public boolean equals(final java.lang.Object obj) {
        if (obj == this) {
         return true;
        }
        if (!(obj instanceof food.menu.v1.FoodMenu.NutritionInformation.NutritionValue)) {
          return super.equals(obj);
        }
        food.menu.v1.FoodMenu.NutritionInformation.NutritionValue other = (food.menu.v1.FoodMenu.NutritionInformation.NutritionValue) obj;

        if (unit_ != other.unit_) return false;
        if (!getValueCase().equals(other.getValueCase())) return false;
        switch (valueCase_) {
          case 1:
            if (java.lang.Double.doubleToLongBits(getAmount())
                != java.lang.Double.doubleToLongBits(
                    other.getAmount())) return false;
            break;
          case 3:
            if (!getRange()
                .equals(other.getRange())) return false;
            break;
          case 0:
          default:
        }
        if (!getUnknownFields().equals(other.getUnknownFields())) return false;
        return true;
      }

      @java.lang.Override
      public int hashCode() {
        if (memoizedHashCode != 0) {
          return memoizedHashCode;
        }
        int hash = 41;
        hash = (19 * hash) + getDescriptor().hashCode();
        hash = (37 * hash) + UNIT_FIELD_NUMBER;
        hash = (53 * hash) + unit_;
        switch (valueCase_) {
          case 1:
            hash = (37 * hash) + AMOUNT_FIELD_NUMBER;
            hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                java.lang.Double.doubleToLongBits(getAmount()));
            break;
          case 3:
            hash = (37 * hash) + RANGE_FIELD_NUMBER;
            hash = (53 * hash) + getRange().hashCode();
            break;
          case 0:
          default:
        }
        hash = (29 * hash) + getUnknownFields().hashCode();
        memoizedHashCode = hash;
        return hash;
      }

      public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue parseFrom(
          java.nio.ByteBuffer data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data);
      }
      public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue parseFrom(
          java.nio.ByteBuffer data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data, extensionRegistry);
      }
      public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue parseFrom(
          com.google.protobuf.ByteString data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data);
      }
      public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue parseFrom(
          com.google.protobuf.ByteString data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data, extensionRegistry);
      }
      public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue parseFrom(byte[] data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data);
      }
      public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue parseFrom(
          byte[] data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data, extensionRegistry);
      }
      public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue parseFrom(java.io.InputStream input)
          throws java.io.IOException {
        return com.google.protobuf.GeneratedMessageV3
            .parseWithIOException(PARSER, input);
      }
      public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue parseFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return com.google.protobuf.GeneratedMessageV3
            .parseWithIOException(PARSER, input, extensionRegistry);
      }
      public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue parseDelimitedFrom(java.io.InputStream input)
          throws java.io.IOException {
        return com.google.protobuf.GeneratedMessageV3
            .parseDelimitedWithIOException(PARSER, input);
      }
      public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue parseDelimitedFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return com.google.protobuf.GeneratedMessageV3
            .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
      }
      public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue parseFrom(
          com.google.protobuf.CodedInputStream input)
          throws java.io.IOException {
        return com.google.protobuf.GeneratedMessageV3
            .parseWithIOException(PARSER, input);
      }
      public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue parseFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return com.google.protobuf.GeneratedMessageV3
            .parseWithIOException(PARSER, input, extensionRegistry);
      }

      @java.lang.Override
      public Builder newBuilderForType() { return newBuilder(); }
      public static Builder newBuilder() {
        return DEFAULT_INSTANCE.toBuilder();
      }
      public static Builder newBuilder(food.menu.v1.FoodMenu.NutritionInformation.NutritionValue prototype) {
        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
      }
      @java.lang.Override
      public Builder toBuilder() {
        return this == DEFAULT_INSTANCE
            ? new Builder() : new Builder().mergeFrom(this);
      }

      @java.lang.Override
      protected Builder newBuilderForType(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        Builder builder = new Builder(parent);
        return builder;
      }
      /**
       * <pre>
       * Describes a single nutritional measurement of the serving of food.
       * </pre>
       *
       * Protobuf type {@code food.menu.v1.NutritionInformation.NutritionValue}
       */
      public static final class Builder extends
          com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
          // @@protoc_insertion_point(builder_implements:food.menu.v1.NutritionInformation.NutritionValue)
          food.menu.v1.FoodMenu.NutritionInformation.NutritionValueOrBuilder {
        public static final com.google.protobuf.Descriptors.Descriptor
            getDescriptor() {
          return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_NutritionValue_descriptor;
        }

        @java.lang.Override
        protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
            internalGetFieldAccessorTable() {
          return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_NutritionValue_fieldAccessorTable
              .ensureFieldAccessorsInitialized(
                  food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.class, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Builder.class);
        }

        // Construct using food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.newBuilder()
        private Builder() {

        }

        private Builder(
            com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
          super(parent);

        }
        @java.lang.Override
        public Builder clear() {
          super.clear();
          bitField0_ = 0;
          if (rangeBuilder_ != null) {
            rangeBuilder_.clear();
          }
          unit_ = 0;
          valueCase_ = 0;
          value_ = null;
          return this;
        }

        @java.lang.Override
        public com.google.protobuf.Descriptors.Descriptor
            getDescriptorForType() {
          return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_NutritionValue_descriptor;
        }

        @java.lang.Override
        public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue getDefaultInstanceForType() {
          return food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.getDefaultInstance();
        }

        @java.lang.Override
        public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue build() {
          food.menu.v1.FoodMenu.NutritionInformation.NutritionValue result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(result);
          }
          return result;
        }

        @java.lang.Override
        public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue buildPartial() {
          food.menu.v1.FoodMenu.NutritionInformation.NutritionValue result = new food.menu.v1.FoodMenu.NutritionInformation.NutritionValue(this);
          if (bitField0_ != 0) { buildPartial0(result); }
          buildPartialOneofs(result);
          onBuilt();
          return result;
        }

        private void buildPartial0(food.menu.v1.FoodMenu.NutritionInformation.NutritionValue result) {
          int from_bitField0_ = bitField0_;
          if (((from_bitField0_ & 0x00000004) != 0)) {
            result.unit_ = unit_;
          }
        }

        private void buildPartialOneofs(food.menu.v1.FoodMenu.NutritionInformation.NutritionValue result) {
          result.valueCase_ = valueCase_;
          result.value_ = this.value_;
          if (valueCase_ == 3 &&
              rangeBuilder_ != null) {
            result.value_ = rangeBuilder_.build();
          }
        }

        @java.lang.Override
        public Builder mergeFrom(com.google.protobuf.Message other) {
          if (other instanceof food.menu.v1.FoodMenu.NutritionInformation.NutritionValue) {
            return mergeFrom((food.menu.v1.FoodMenu.NutritionInformation.NutritionValue)other);
          } else {
            super.mergeFrom(other);
            return this;
          }
        }

        public Builder mergeFrom(food.menu.v1.FoodMenu.NutritionInformation.NutritionValue other) {
          if (other == food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.getDefaultInstance()) return this;
          if (other.unit_ != 0) {
            setUnitValue(other.getUnitValue());
          }
          switch (other.getValueCase()) {
            case AMOUNT: {
              setAmount(other.getAmount());
              break;
            }
            case RANGE: {
              mergeRange(other.getRange());
              break;
            }
            case VALUE_NOT_SET: {
              break;
            }
          }
          this.mergeUnknownFields(other.getUnknownFields());
          onChanged();
          return this;
        }

        @java.lang.Override
        public final boolean isInitialized() {
          return true;
        }

        @java.lang.Override
        public Builder mergeFrom(
            com.google.protobuf.CodedInputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws java.io.IOException {
          if (extensionRegistry == null) {
            throw new java.lang.NullPointerException();
          }
          try {
            boolean done = false;
            while (!done) {
              int tag = input.readTag();
              switch (tag) {
                case 0:
                  done = true;
                  break;
                case 9: {
                  value_ = input.readDouble();
                  valueCase_ = 1;
                  break;
                } // case 9
                case 16: {
                  unit_ = input.readEnum();
                  bitField0_ |= 0x00000004;
                  break;
                } // case 16
                case 26: {
                  input.readMessage(
                      getRangeFieldBuilder().getBuilder(),
                      extensionRegistry);
                  valueCase_ = 3;
                  break;
                } // case 26
                default: {
                  if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                    done = true; // was an endgroup tag
                  }
                  break;
                } // default:
              } // switch (tag)
            } // while (!done)
          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
            throw e.unwrapIOException();
          } finally {
            onChanged();
          } // finally
          return this;
        }
        private int valueCase_ = 0;
        private java.lang.Object value_;
        public ValueCase
            getValueCase() {
          return ValueCase.forNumber(
              valueCase_);
        }

        public Builder clearValue() {
          valueCase_ = 0;
          value_ = null;
          onChanged();
          return this;
        }

        private int bitField0_;

        /**
         * <pre>
         * A single number representing the amount of nutritional value.
         * </pre>
         *
         * <code>double amount = 1;</code>
         * @return Whether the amount field is set.
         */
        public boolean hasAmount() {
          return valueCase_ == 1;
        }
        /**
         * <pre>
         * A single number representing the amount of nutritional value.
         * </pre>
         *
         * <code>double amount = 1;</code>
         * @return The amount.
         */
        public double getAmount() {
          if (valueCase_ == 1) {
            return (java.lang.Double) value_;
          }
          return 0D;
        }
        /**
         * <pre>
         * A single number representing the amount of nutritional value.
         * </pre>
         *
         * <code>double amount = 1;</code>
         * @param value The amount to set.
         * @return This builder for chaining.
         */
        public Builder setAmount(double value) {

          valueCase_ = 1;
          value_ = value;
          onChanged();
          return this;
        }
        /**
         * <pre>
         * A single number representing the amount of nutritional value.
         * </pre>
         *
         * <code>double amount = 1;</code>
         * @return This builder for chaining.
         */
        public Builder clearAmount() {
          if (valueCase_ == 1) {
            valueCase_ = 0;
            value_ = null;
            onChanged();
          }
          return this;
        }

        private com.google.protobuf.SingleFieldBuilderV3<
            food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.Builder, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.RangeOrBuilder> rangeBuilder_;
        /**
         * <pre>
         * A range representing the amount of nutritional value.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
         * @return Whether the range field is set.
         */
        @java.lang.Override
        public boolean hasRange() {
          return valueCase_ == 3;
        }
        /**
         * <pre>
         * A range representing the amount of nutritional value.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
         * @return The range.
         */
        @java.lang.Override
        public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range getRange() {
          if (rangeBuilder_ == null) {
            if (valueCase_ == 3) {
              return (food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range) value_;
            }
            return food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.getDefaultInstance();
          } else {
            if (valueCase_ == 3) {
              return rangeBuilder_.getMessage();
            }
            return food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.getDefaultInstance();
          }
        }
        /**
         * <pre>
         * A range representing the amount of nutritional value.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
         */
        public Builder setRange(food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range value) {
          if (rangeBuilder_ == null) {
            if (value == null) {
              throw new NullPointerException();
            }
            value_ = value;
            onChanged();
          } else {
            rangeBuilder_.setMessage(value);
          }
          valueCase_ = 3;
          return this;
        }
        /**
         * <pre>
         * A range representing the amount of nutritional value.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
         */
        public Builder setRange(
            food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.Builder builderForValue) {
          if (rangeBuilder_ == null) {
            value_ = builderForValue.build();
            onChanged();
          } else {
            rangeBuilder_.setMessage(builderForValue.build());
          }
          valueCase_ = 3;
          return this;
        }
        /**
         * <pre>
         * A range representing the amount of nutritional value.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
         */
        public Builder mergeRange(food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range value) {
          if (rangeBuilder_ == null) {
            if (valueCase_ == 3 &&
                value_ != food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.getDefaultInstance()) {
              value_ = food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.newBuilder((food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range) value_)
                  .mergeFrom(value).buildPartial();
            } else {
              value_ = value;
            }
            onChanged();
          } else {
            if (valueCase_ == 3) {
              rangeBuilder_.mergeFrom(value);
            } else {
              rangeBuilder_.setMessage(value);
            }
          }
          valueCase_ = 3;
          return this;
        }
        /**
         * <pre>
         * A range representing the amount of nutritional value.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
         */
        public Builder clearRange() {
          if (rangeBuilder_ == null) {
            if (valueCase_ == 3) {
              valueCase_ = 0;
              value_ = null;
              onChanged();
            }
          } else {
            if (valueCase_ == 3) {
              valueCase_ = 0;
              value_ = null;
            }
            rangeBuilder_.clear();
          }
          return this;
        }
        /**
         * <pre>
         * A range representing the amount of nutritional value.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
         */
        public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.Builder getRangeBuilder() {
          return getRangeFieldBuilder().getBuilder();
        }
        /**
         * <pre>
         * A range representing the amount of nutritional value.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
         */
        @java.lang.Override
        public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.RangeOrBuilder getRangeOrBuilder() {
          if ((valueCase_ == 3) && (rangeBuilder_ != null)) {
            return rangeBuilder_.getMessageOrBuilder();
          } else {
            if (valueCase_ == 3) {
              return (food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range) value_;
            }
            return food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.getDefaultInstance();
          }
        }
        /**
         * <pre>
         * A range representing the amount of nutritional value.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionInformation.NutritionValue.Range range = 3;</code>
         */
        private com.google.protobuf.SingleFieldBuilderV3<
            food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.Builder, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.RangeOrBuilder> 
            getRangeFieldBuilder() {
          if (rangeBuilder_ == null) {
            if (!(valueCase_ == 3)) {
              value_ = food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.getDefaultInstance();
            }
            rangeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
                food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range.Builder, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.RangeOrBuilder>(
                    (food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Range) value_,
                    getParentForChildren(),
                    isClean());
            value_ = null;
          }
          valueCase_ = 3;
          onChanged();
          return rangeBuilder_;
        }

        private int unit_ = 0;
        /**
         * <pre>
         * The unit associated with the amount as specified from the partner. We
         * will validate the feed so that the unit for each type of nutrition value
         * is expected for that type of value. For example, only ENERGY_CALORIES
         * and ENERGY_KILOJOULES are expected on energy property of
         * NutritionalInformation.
         * Required.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionValueUnit unit = 2;</code>
         * @return The enum numeric value on the wire for unit.
         */
        @java.lang.Override public int getUnitValue() {
          return unit_;
        }
        /**
         * <pre>
         * The unit associated with the amount as specified from the partner. We
         * will validate the feed so that the unit for each type of nutrition value
         * is expected for that type of value. For example, only ENERGY_CALORIES
         * and ENERGY_KILOJOULES are expected on energy property of
         * NutritionalInformation.
         * Required.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionValueUnit unit = 2;</code>
         * @param value The enum numeric value on the wire for unit to set.
         * @return This builder for chaining.
         */
        public Builder setUnitValue(int value) {
          unit_ = value;
          bitField0_ |= 0x00000004;
          onChanged();
          return this;
        }
        /**
         * <pre>
         * The unit associated with the amount as specified from the partner. We
         * will validate the feed so that the unit for each type of nutrition value
         * is expected for that type of value. For example, only ENERGY_CALORIES
         * and ENERGY_KILOJOULES are expected on energy property of
         * NutritionalInformation.
         * Required.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionValueUnit unit = 2;</code>
         * @return The unit.
         */
        @java.lang.Override
        public food.menu.v1.FoodMenu.NutritionValueUnit getUnit() {
          food.menu.v1.FoodMenu.NutritionValueUnit result = food.menu.v1.FoodMenu.NutritionValueUnit.forNumber(unit_);
          return result == null ? food.menu.v1.FoodMenu.NutritionValueUnit.UNRECOGNIZED : result;
        }
        /**
         * <pre>
         * The unit associated with the amount as specified from the partner. We
         * will validate the feed so that the unit for each type of nutrition value
         * is expected for that type of value. For example, only ENERGY_CALORIES
         * and ENERGY_KILOJOULES are expected on energy property of
         * NutritionalInformation.
         * Required.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionValueUnit unit = 2;</code>
         * @param value The unit to set.
         * @return This builder for chaining.
         */
        public Builder setUnit(food.menu.v1.FoodMenu.NutritionValueUnit value) {
          if (value == null) {
            throw new NullPointerException();
          }
          bitField0_ |= 0x00000004;
          unit_ = value.getNumber();
          onChanged();
          return this;
        }
        /**
         * <pre>
         * The unit associated with the amount as specified from the partner. We
         * will validate the feed so that the unit for each type of nutrition value
         * is expected for that type of value. For example, only ENERGY_CALORIES
         * and ENERGY_KILOJOULES are expected on energy property of
         * NutritionalInformation.
         * Required.
         * </pre>
         *
         * <code>.food.menu.v1.NutritionValueUnit unit = 2;</code>
         * @return This builder for chaining.
         */
        public Builder clearUnit() {
          bitField0_ = (bitField0_ & ~0x00000004);
          unit_ = 0;
          onChanged();
          return this;
        }
        @java.lang.Override
        public final Builder setUnknownFields(
            final com.google.protobuf.UnknownFieldSet unknownFields) {
          return super.setUnknownFields(unknownFields);
        }

        @java.lang.Override
        public final Builder mergeUnknownFields(
            final com.google.protobuf.UnknownFieldSet unknownFields) {
          return super.mergeUnknownFields(unknownFields);
        }


        // @@protoc_insertion_point(builder_scope:food.menu.v1.NutritionInformation.NutritionValue)
      }

      // @@protoc_insertion_point(class_scope:food.menu.v1.NutritionInformation.NutritionValue)
      private static final food.menu.v1.FoodMenu.NutritionInformation.NutritionValue DEFAULT_INSTANCE;
      static {
        DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.NutritionInformation.NutritionValue();
      }

      public static food.menu.v1.FoodMenu.NutritionInformation.NutritionValue getDefaultInstance() {
        return DEFAULT_INSTANCE;
      }

      private static final com.google.protobuf.Parser<NutritionValue>
          PARSER = new com.google.protobuf.AbstractParser<NutritionValue>() {
        @java.lang.Override
        public NutritionValue parsePartialFrom(
            com.google.protobuf.CodedInputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws com.google.protobuf.InvalidProtocolBufferException {
          Builder builder = newBuilder();
          try {
            builder.mergeFrom(input, extensionRegistry);
          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
            throw e.setUnfinishedMessage(builder.buildPartial());
          } catch (com.google.protobuf.UninitializedMessageException e) {
            throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
          } catch (java.io.IOException e) {
            throw new com.google.protobuf.InvalidProtocolBufferException(e)
                .setUnfinishedMessage(builder.buildPartial());
          }
          return builder.buildPartial();
        }
      };

      public static com.google.protobuf.Parser<NutritionValue> parser() {
        return PARSER;
      }

      @java.lang.Override
      public com.google.protobuf.Parser<NutritionValue> getParserForType() {
        return PARSER;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue getDefaultInstanceForType() {
        return DEFAULT_INSTANCE;
      }

    }

    private int bitField0_;
    public static final int ENERGY_FIELD_NUMBER = 1;
    private food.menu.v1.FoodMenu.NutritionInformation.NutritionValue energy_;
    /**
     * <pre>
     * The amount of nutritional energy of the serving of food. Can be defined
     * in Calories or kilojoules.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
     * @return Whether the energy field is set.
     */
    @java.lang.Override
    public boolean hasEnergy() {
      return energy_ != null;
    }
    /**
     * <pre>
     * The amount of nutritional energy of the serving of food. Can be defined
     * in Calories or kilojoules.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
     * @return The energy.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue getEnergy() {
      return energy_ == null ? food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.getDefaultInstance() : energy_;
    }
    /**
     * <pre>
     * The amount of nutritional energy of the serving of food. Can be defined
     * in Calories or kilojoules.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.NutritionInformation.NutritionValueOrBuilder getEnergyOrBuilder() {
      return energy_ == null ? food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.getDefaultInstance() : energy_;
    }

    public static final int SODIUM_CONTENT_FIELD_NUMBER = 2;
    private food.menu.v1.FoodMenu.NutritionInformation.NutritionValue sodiumContent_;
    /**
     * <pre>
     * The amount of sodium content, measured in grams or milligrams.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
     * @return Whether the sodiumContent field is set.
     */
    @java.lang.Override
    public boolean hasSodiumContent() {
      return sodiumContent_ != null;
    }
    /**
     * <pre>
     * The amount of sodium content, measured in grams or milligrams.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
     * @return The sodiumContent.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue getSodiumContent() {
      return sodiumContent_ == null ? food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.getDefaultInstance() : sodiumContent_;
    }
    /**
     * <pre>
     * The amount of sodium content, measured in grams or milligrams.
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.NutritionInformation.NutritionValueOrBuilder getSodiumContentOrBuilder() {
      return sodiumContent_ == null ? food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.getDefaultInstance() : sodiumContent_;
    }

    public static final int SERVING_SIZE_FIELD_NUMBER = 3;
    private int servingSize_ = 0;
    /**
     * <pre>
     * The number of servings the nutrition value applies to.
     * Optional.
     * </pre>
     *
     * <code>optional int32 serving_size = 3;</code>
     * @return Whether the servingSize field is set.
     */
    @java.lang.Override
    public boolean hasServingSize() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * The number of servings the nutrition value applies to.
     * Optional.
     * </pre>
     *
     * <code>optional int32 serving_size = 3;</code>
     * @return The servingSize.
     */
    @java.lang.Override
    public int getServingSize() {
      return servingSize_;
    }

    public static final int DESCRIPTION_FIELD_NUMBER = 4;
    private food.menu.v1.FoodMenu.TextField description_;
    /**
     * <pre>
     * Nutrition information in free text. For example "Contains preservatives".
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 4;</code>
     * @return Whether the description field is set.
     */
    @java.lang.Override
    public boolean hasDescription() {
      return description_ != null;
    }
    /**
     * <pre>
     * Nutrition information in free text. For example "Contains preservatives".
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 4;</code>
     * @return The description.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextField getDescription() {
      return description_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : description_;
    }
    /**
     * <pre>
     * Nutrition information in free text. For example "Contains preservatives".
     * Optional.
     * </pre>
     *
     * <code>.food.menu.v1.TextField description = 4;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextFieldOrBuilder getDescriptionOrBuilder() {
      return description_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : description_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (energy_ != null) {
        output.writeMessage(1, getEnergy());
      }
      if (sodiumContent_ != null) {
        output.writeMessage(2, getSodiumContent());
      }
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(3, servingSize_);
      }
      if (description_ != null) {
        output.writeMessage(4, getDescription());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (energy_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getEnergy());
      }
      if (sodiumContent_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getSodiumContent());
      }
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, servingSize_);
      }
      if (description_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, getDescription());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.NutritionInformation)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.NutritionInformation other = (food.menu.v1.FoodMenu.NutritionInformation) obj;

      if (hasEnergy() != other.hasEnergy()) return false;
      if (hasEnergy()) {
        if (!getEnergy()
            .equals(other.getEnergy())) return false;
      }
      if (hasSodiumContent() != other.hasSodiumContent()) return false;
      if (hasSodiumContent()) {
        if (!getSodiumContent()
            .equals(other.getSodiumContent())) return false;
      }
      if (hasServingSize() != other.hasServingSize()) return false;
      if (hasServingSize()) {
        if (getServingSize()
            != other.getServingSize()) return false;
      }
      if (hasDescription() != other.hasDescription()) return false;
      if (hasDescription()) {
        if (!getDescription()
            .equals(other.getDescription())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasEnergy()) {
        hash = (37 * hash) + ENERGY_FIELD_NUMBER;
        hash = (53 * hash) + getEnergy().hashCode();
      }
      if (hasSodiumContent()) {
        hash = (37 * hash) + SODIUM_CONTENT_FIELD_NUMBER;
        hash = (53 * hash) + getSodiumContent().hashCode();
      }
      if (hasServingSize()) {
        hash = (37 * hash) + SERVING_SIZE_FIELD_NUMBER;
        hash = (53 * hash) + getServingSize();
      }
      if (hasDescription()) {
        hash = (37 * hash) + DESCRIPTION_FIELD_NUMBER;
        hash = (53 * hash) + getDescription().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.NutritionInformation parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.NutritionInformation parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.NutritionInformation parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.NutritionInformation parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.NutritionInformation parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.NutritionInformation parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.NutritionInformation parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.NutritionInformation parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.NutritionInformation parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.NutritionInformation parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.NutritionInformation parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.NutritionInformation parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.NutritionInformation prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Describes all the nutritional measurements of a MenuItem or add-on.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.NutritionInformation}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.NutritionInformation)
        food.menu.v1.FoodMenu.NutritionInformationOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.NutritionInformation.class, food.menu.v1.FoodMenu.NutritionInformation.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.NutritionInformation.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        energy_ = null;
        if (energyBuilder_ != null) {
          energyBuilder_.dispose();
          energyBuilder_ = null;
        }
        sodiumContent_ = null;
        if (sodiumContentBuilder_ != null) {
          sodiumContentBuilder_.dispose();
          sodiumContentBuilder_ = null;
        }
        servingSize_ = 0;
        description_ = null;
        if (descriptionBuilder_ != null) {
          descriptionBuilder_.dispose();
          descriptionBuilder_ = null;
        }
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_NutritionInformation_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.NutritionInformation getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.NutritionInformation.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.NutritionInformation build() {
        food.menu.v1.FoodMenu.NutritionInformation result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.NutritionInformation buildPartial() {
        food.menu.v1.FoodMenu.NutritionInformation result = new food.menu.v1.FoodMenu.NutritionInformation(this);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartial0(food.menu.v1.FoodMenu.NutritionInformation result) {
        int from_bitField0_ = bitField0_;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.energy_ = energyBuilder_ == null
              ? energy_
              : energyBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.sodiumContent_ = sodiumContentBuilder_ == null
              ? sodiumContent_
              : sodiumContentBuilder_.build();
        }
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.servingSize_ = servingSize_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.description_ = descriptionBuilder_ == null
              ? description_
              : descriptionBuilder_.build();
        }
        result.bitField0_ |= to_bitField0_;
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.NutritionInformation) {
          return mergeFrom((food.menu.v1.FoodMenu.NutritionInformation)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.NutritionInformation other) {
        if (other == food.menu.v1.FoodMenu.NutritionInformation.getDefaultInstance()) return this;
        if (other.hasEnergy()) {
          mergeEnergy(other.getEnergy());
        }
        if (other.hasSodiumContent()) {
          mergeSodiumContent(other.getSodiumContent());
        }
        if (other.hasServingSize()) {
          setServingSize(other.getServingSize());
        }
        if (other.hasDescription()) {
          mergeDescription(other.getDescription());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getEnergyFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                input.readMessage(
                    getSodiumContentFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 24: {
                servingSize_ = input.readInt32();
                bitField0_ |= 0x00000004;
                break;
              } // case 24
              case 34: {
                input.readMessage(
                    getDescriptionFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private food.menu.v1.FoodMenu.NutritionInformation.NutritionValue energy_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.NutritionInformation.NutritionValue, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Builder, food.menu.v1.FoodMenu.NutritionInformation.NutritionValueOrBuilder> energyBuilder_;
      /**
       * <pre>
       * The amount of nutritional energy of the serving of food. Can be defined
       * in Calories or kilojoules.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
       * @return Whether the energy field is set.
       */
      public boolean hasEnergy() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * The amount of nutritional energy of the serving of food. Can be defined
       * in Calories or kilojoules.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
       * @return The energy.
       */
      public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue getEnergy() {
        if (energyBuilder_ == null) {
          return energy_ == null ? food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.getDefaultInstance() : energy_;
        } else {
          return energyBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * The amount of nutritional energy of the serving of food. Can be defined
       * in Calories or kilojoules.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
       */
      public Builder setEnergy(food.menu.v1.FoodMenu.NutritionInformation.NutritionValue value) {
        if (energyBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          energy_ = value;
        } else {
          energyBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The amount of nutritional energy of the serving of food. Can be defined
       * in Calories or kilojoules.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
       */
      public Builder setEnergy(
          food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Builder builderForValue) {
        if (energyBuilder_ == null) {
          energy_ = builderForValue.build();
        } else {
          energyBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The amount of nutritional energy of the serving of food. Can be defined
       * in Calories or kilojoules.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
       */
      public Builder mergeEnergy(food.menu.v1.FoodMenu.NutritionInformation.NutritionValue value) {
        if (energyBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
            energy_ != null &&
            energy_ != food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.getDefaultInstance()) {
            getEnergyBuilder().mergeFrom(value);
          } else {
            energy_ = value;
          }
        } else {
          energyBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The amount of nutritional energy of the serving of food. Can be defined
       * in Calories or kilojoules.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
       */
      public Builder clearEnergy() {
        bitField0_ = (bitField0_ & ~0x00000001);
        energy_ = null;
        if (energyBuilder_ != null) {
          energyBuilder_.dispose();
          energyBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The amount of nutritional energy of the serving of food. Can be defined
       * in Calories or kilojoules.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
       */
      public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Builder getEnergyBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getEnergyFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * The amount of nutritional energy of the serving of food. Can be defined
       * in Calories or kilojoules.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
       */
      public food.menu.v1.FoodMenu.NutritionInformation.NutritionValueOrBuilder getEnergyOrBuilder() {
        if (energyBuilder_ != null) {
          return energyBuilder_.getMessageOrBuilder();
        } else {
          return energy_ == null ?
              food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.getDefaultInstance() : energy_;
        }
      }
      /**
       * <pre>
       * The amount of nutritional energy of the serving of food. Can be defined
       * in Calories or kilojoules.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue energy = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.NutritionInformation.NutritionValue, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Builder, food.menu.v1.FoodMenu.NutritionInformation.NutritionValueOrBuilder> 
          getEnergyFieldBuilder() {
        if (energyBuilder_ == null) {
          energyBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.NutritionInformation.NutritionValue, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Builder, food.menu.v1.FoodMenu.NutritionInformation.NutritionValueOrBuilder>(
                  getEnergy(),
                  getParentForChildren(),
                  isClean());
          energy_ = null;
        }
        return energyBuilder_;
      }

      private food.menu.v1.FoodMenu.NutritionInformation.NutritionValue sodiumContent_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.NutritionInformation.NutritionValue, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Builder, food.menu.v1.FoodMenu.NutritionInformation.NutritionValueOrBuilder> sodiumContentBuilder_;
      /**
       * <pre>
       * The amount of sodium content, measured in grams or milligrams.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
       * @return Whether the sodiumContent field is set.
       */
      public boolean hasSodiumContent() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * The amount of sodium content, measured in grams or milligrams.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
       * @return The sodiumContent.
       */
      public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue getSodiumContent() {
        if (sodiumContentBuilder_ == null) {
          return sodiumContent_ == null ? food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.getDefaultInstance() : sodiumContent_;
        } else {
          return sodiumContentBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * The amount of sodium content, measured in grams or milligrams.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
       */
      public Builder setSodiumContent(food.menu.v1.FoodMenu.NutritionInformation.NutritionValue value) {
        if (sodiumContentBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          sodiumContent_ = value;
        } else {
          sodiumContentBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The amount of sodium content, measured in grams or milligrams.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
       */
      public Builder setSodiumContent(
          food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Builder builderForValue) {
        if (sodiumContentBuilder_ == null) {
          sodiumContent_ = builderForValue.build();
        } else {
          sodiumContentBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The amount of sodium content, measured in grams or milligrams.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
       */
      public Builder mergeSodiumContent(food.menu.v1.FoodMenu.NutritionInformation.NutritionValue value) {
        if (sodiumContentBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
            sodiumContent_ != null &&
            sodiumContent_ != food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.getDefaultInstance()) {
            getSodiumContentBuilder().mergeFrom(value);
          } else {
            sodiumContent_ = value;
          }
        } else {
          sodiumContentBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The amount of sodium content, measured in grams or milligrams.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
       */
      public Builder clearSodiumContent() {
        bitField0_ = (bitField0_ & ~0x00000002);
        sodiumContent_ = null;
        if (sodiumContentBuilder_ != null) {
          sodiumContentBuilder_.dispose();
          sodiumContentBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The amount of sodium content, measured in grams or milligrams.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
       */
      public food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Builder getSodiumContentBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getSodiumContentFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * The amount of sodium content, measured in grams or milligrams.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
       */
      public food.menu.v1.FoodMenu.NutritionInformation.NutritionValueOrBuilder getSodiumContentOrBuilder() {
        if (sodiumContentBuilder_ != null) {
          return sodiumContentBuilder_.getMessageOrBuilder();
        } else {
          return sodiumContent_ == null ?
              food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.getDefaultInstance() : sodiumContent_;
        }
      }
      /**
       * <pre>
       * The amount of sodium content, measured in grams or milligrams.
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.NutritionInformation.NutritionValue sodium_content = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.NutritionInformation.NutritionValue, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Builder, food.menu.v1.FoodMenu.NutritionInformation.NutritionValueOrBuilder> 
          getSodiumContentFieldBuilder() {
        if (sodiumContentBuilder_ == null) {
          sodiumContentBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.NutritionInformation.NutritionValue, food.menu.v1.FoodMenu.NutritionInformation.NutritionValue.Builder, food.menu.v1.FoodMenu.NutritionInformation.NutritionValueOrBuilder>(
                  getSodiumContent(),
                  getParentForChildren(),
                  isClean());
          sodiumContent_ = null;
        }
        return sodiumContentBuilder_;
      }

      private int servingSize_ ;
      /**
       * <pre>
       * The number of servings the nutrition value applies to.
       * Optional.
       * </pre>
       *
       * <code>optional int32 serving_size = 3;</code>
       * @return Whether the servingSize field is set.
       */
      @java.lang.Override
      public boolean hasServingSize() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <pre>
       * The number of servings the nutrition value applies to.
       * Optional.
       * </pre>
       *
       * <code>optional int32 serving_size = 3;</code>
       * @return The servingSize.
       */
      @java.lang.Override
      public int getServingSize() {
        return servingSize_;
      }
      /**
       * <pre>
       * The number of servings the nutrition value applies to.
       * Optional.
       * </pre>
       *
       * <code>optional int32 serving_size = 3;</code>
       * @param value The servingSize to set.
       * @return This builder for chaining.
       */
      public Builder setServingSize(int value) {

        servingSize_ = value;
        bitField0_ |= 0x00000004;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The number of servings the nutrition value applies to.
       * Optional.
       * </pre>
       *
       * <code>optional int32 serving_size = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearServingSize() {
        bitField0_ = (bitField0_ & ~0x00000004);
        servingSize_ = 0;
        onChanged();
        return this;
      }

      private food.menu.v1.FoodMenu.TextField description_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> descriptionBuilder_;
      /**
       * <pre>
       * Nutrition information in free text. For example "Contains preservatives".
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 4;</code>
       * @return Whether the description field is set.
       */
      public boolean hasDescription() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <pre>
       * Nutrition information in free text. For example "Contains preservatives".
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 4;</code>
       * @return The description.
       */
      public food.menu.v1.FoodMenu.TextField getDescription() {
        if (descriptionBuilder_ == null) {
          return description_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : description_;
        } else {
          return descriptionBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Nutrition information in free text. For example "Contains preservatives".
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 4;</code>
       */
      public Builder setDescription(food.menu.v1.FoodMenu.TextField value) {
        if (descriptionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          description_ = value;
        } else {
          descriptionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Nutrition information in free text. For example "Contains preservatives".
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 4;</code>
       */
      public Builder setDescription(
          food.menu.v1.FoodMenu.TextField.Builder builderForValue) {
        if (descriptionBuilder_ == null) {
          description_ = builderForValue.build();
        } else {
          descriptionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Nutrition information in free text. For example "Contains preservatives".
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 4;</code>
       */
      public Builder mergeDescription(food.menu.v1.FoodMenu.TextField value) {
        if (descriptionBuilder_ == null) {
          if (((bitField0_ & 0x00000008) != 0) &&
            description_ != null &&
            description_ != food.menu.v1.FoodMenu.TextField.getDefaultInstance()) {
            getDescriptionBuilder().mergeFrom(value);
          } else {
            description_ = value;
          }
        } else {
          descriptionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Nutrition information in free text. For example "Contains preservatives".
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 4;</code>
       */
      public Builder clearDescription() {
        bitField0_ = (bitField0_ & ~0x00000008);
        description_ = null;
        if (descriptionBuilder_ != null) {
          descriptionBuilder_.dispose();
          descriptionBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Nutrition information in free text. For example "Contains preservatives".
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 4;</code>
       */
      public food.menu.v1.FoodMenu.TextField.Builder getDescriptionBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getDescriptionFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Nutrition information in free text. For example "Contains preservatives".
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 4;</code>
       */
      public food.menu.v1.FoodMenu.TextFieldOrBuilder getDescriptionOrBuilder() {
        if (descriptionBuilder_ != null) {
          return descriptionBuilder_.getMessageOrBuilder();
        } else {
          return description_ == null ?
              food.menu.v1.FoodMenu.TextField.getDefaultInstance() : description_;
        }
      }
      /**
       * <pre>
       * Nutrition information in free text. For example "Contains preservatives".
       * Optional.
       * </pre>
       *
       * <code>.food.menu.v1.TextField description = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> 
          getDescriptionFieldBuilder() {
        if (descriptionBuilder_ == null) {
          descriptionBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder>(
                  getDescription(),
                  getParentForChildren(),
                  isClean());
          description_ = null;
        }
        return descriptionBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.NutritionInformation)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.NutritionInformation)
    private static final food.menu.v1.FoodMenu.NutritionInformation DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.NutritionInformation();
    }

    public static food.menu.v1.FoodMenu.NutritionInformation getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<NutritionInformation>
        PARSER = new com.google.protobuf.AbstractParser<NutritionInformation>() {
      @java.lang.Override
      public NutritionInformation parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<NutritionInformation> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<NutritionInformation> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.NutritionInformation getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface AdditiveOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.Additive)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * Descriptive text of the additive, e.g. "preservatives".
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField name = 1;</code>
     * @return Whether the name field is set.
     */
    boolean hasName();
    /**
     * <pre>
     * Descriptive text of the additive, e.g. "preservatives".
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField name = 1;</code>
     * @return The name.
     */
    food.menu.v1.FoodMenu.TextField getName();
    /**
     * <pre>
     * Descriptive text of the additive, e.g. "preservatives".
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField name = 1;</code>
     */
    food.menu.v1.FoodMenu.TextFieldOrBuilder getNameOrBuilder();

    /**
     * <pre>
     * Whether the MenuItem contains, may contain, or is free from this additive.
     * Defaults to contains.
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
     * @return Whether the containmentLevelCode field is set.
     */
    boolean hasContainmentLevelCode();
    /**
     * <pre>
     * Whether the MenuItem contains, may contain, or is free from this additive.
     * Defaults to contains.
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
     * @return The enum numeric value on the wire for containmentLevelCode.
     */
    int getContainmentLevelCodeValue();
    /**
     * <pre>
     * Whether the MenuItem contains, may contain, or is free from this additive.
     * Defaults to contains.
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
     * @return The containmentLevelCode.
     */
    food.menu.v1.FoodMenu.ContainmentLevelCode getContainmentLevelCode();
  }
  /**
   * <pre>
   * Additive shown to the user on the MenuItem. An additive preserves or enhances
   * the quality of the food.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.Additive}
   */
  public static final class Additive extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.Additive)
      AdditiveOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Additive.newBuilder() to construct.
    private Additive(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Additive() {
      containmentLevelCode_ = 0;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new Additive();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Additive_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Additive_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.Additive.class, food.menu.v1.FoodMenu.Additive.Builder.class);
    }

    private int bitField0_;
    public static final int NAME_FIELD_NUMBER = 1;
    private food.menu.v1.FoodMenu.TextField name_;
    /**
     * <pre>
     * Descriptive text of the additive, e.g. "preservatives".
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField name = 1;</code>
     * @return Whether the name field is set.
     */
    @java.lang.Override
    public boolean hasName() {
      return name_ != null;
    }
    /**
     * <pre>
     * Descriptive text of the additive, e.g. "preservatives".
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField name = 1;</code>
     * @return The name.
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextField getName() {
      return name_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : name_;
    }
    /**
     * <pre>
     * Descriptive text of the additive, e.g. "preservatives".
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.TextField name = 1;</code>
     */
    @java.lang.Override
    public food.menu.v1.FoodMenu.TextFieldOrBuilder getNameOrBuilder() {
      return name_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : name_;
    }

    public static final int CONTAINMENT_LEVEL_CODE_FIELD_NUMBER = 2;
    private int containmentLevelCode_ = 0;
    /**
     * <pre>
     * Whether the MenuItem contains, may contain, or is free from this additive.
     * Defaults to contains.
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
     * @return Whether the containmentLevelCode field is set.
     */
    @java.lang.Override public boolean hasContainmentLevelCode() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * Whether the MenuItem contains, may contain, or is free from this additive.
     * Defaults to contains.
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
     * @return The enum numeric value on the wire for containmentLevelCode.
     */
    @java.lang.Override public int getContainmentLevelCodeValue() {
      return containmentLevelCode_;
    }
    /**
     * <pre>
     * Whether the MenuItem contains, may contain, or is free from this additive.
     * Defaults to contains.
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
     * @return The containmentLevelCode.
     */
    @java.lang.Override public food.menu.v1.FoodMenu.ContainmentLevelCode getContainmentLevelCode() {
      food.menu.v1.FoodMenu.ContainmentLevelCode result = food.menu.v1.FoodMenu.ContainmentLevelCode.forNumber(containmentLevelCode_);
      return result == null ? food.menu.v1.FoodMenu.ContainmentLevelCode.UNRECOGNIZED : result;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (name_ != null) {
        output.writeMessage(1, getName());
      }
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(2, containmentLevelCode_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (name_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getName());
      }
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(2, containmentLevelCode_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.Additive)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.Additive other = (food.menu.v1.FoodMenu.Additive) obj;

      if (hasName() != other.hasName()) return false;
      if (hasName()) {
        if (!getName()
            .equals(other.getName())) return false;
      }
      if (hasContainmentLevelCode() != other.hasContainmentLevelCode()) return false;
      if (hasContainmentLevelCode()) {
        if (containmentLevelCode_ != other.containmentLevelCode_) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasName()) {
        hash = (37 * hash) + NAME_FIELD_NUMBER;
        hash = (53 * hash) + getName().hashCode();
      }
      if (hasContainmentLevelCode()) {
        hash = (37 * hash) + CONTAINMENT_LEVEL_CODE_FIELD_NUMBER;
        hash = (53 * hash) + containmentLevelCode_;
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.Additive parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Additive parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Additive parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Additive parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Additive parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Additive parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Additive parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Additive parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Additive parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Additive parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Additive parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Additive parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.Additive prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Additive shown to the user on the MenuItem. An additive preserves or enhances
     * the quality of the food.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.Additive}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.Additive)
        food.menu.v1.FoodMenu.AdditiveOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Additive_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Additive_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.Additive.class, food.menu.v1.FoodMenu.Additive.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.Additive.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        name_ = null;
        if (nameBuilder_ != null) {
          nameBuilder_.dispose();
          nameBuilder_ = null;
        }
        containmentLevelCode_ = 0;
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Additive_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Additive getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.Additive.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Additive build() {
        food.menu.v1.FoodMenu.Additive result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Additive buildPartial() {
        food.menu.v1.FoodMenu.Additive result = new food.menu.v1.FoodMenu.Additive(this);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartial0(food.menu.v1.FoodMenu.Additive result) {
        int from_bitField0_ = bitField0_;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.name_ = nameBuilder_ == null
              ? name_
              : nameBuilder_.build();
        }
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.containmentLevelCode_ = containmentLevelCode_;
          to_bitField0_ |= 0x00000001;
        }
        result.bitField0_ |= to_bitField0_;
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.Additive) {
          return mergeFrom((food.menu.v1.FoodMenu.Additive)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.Additive other) {
        if (other == food.menu.v1.FoodMenu.Additive.getDefaultInstance()) return this;
        if (other.hasName()) {
          mergeName(other.getName());
        }
        if (other.hasContainmentLevelCode()) {
          setContainmentLevelCode(other.getContainmentLevelCode());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getNameFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 16: {
                containmentLevelCode_ = input.readEnum();
                bitField0_ |= 0x00000002;
                break;
              } // case 16
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private food.menu.v1.FoodMenu.TextField name_;
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> nameBuilder_;
      /**
       * <pre>
       * Descriptive text of the additive, e.g. "preservatives".
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField name = 1;</code>
       * @return Whether the name field is set.
       */
      public boolean hasName() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * Descriptive text of the additive, e.g. "preservatives".
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField name = 1;</code>
       * @return The name.
       */
      public food.menu.v1.FoodMenu.TextField getName() {
        if (nameBuilder_ == null) {
          return name_ == null ? food.menu.v1.FoodMenu.TextField.getDefaultInstance() : name_;
        } else {
          return nameBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Descriptive text of the additive, e.g. "preservatives".
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField name = 1;</code>
       */
      public Builder setName(food.menu.v1.FoodMenu.TextField value) {
        if (nameBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          name_ = value;
        } else {
          nameBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Descriptive text of the additive, e.g. "preservatives".
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField name = 1;</code>
       */
      public Builder setName(
          food.menu.v1.FoodMenu.TextField.Builder builderForValue) {
        if (nameBuilder_ == null) {
          name_ = builderForValue.build();
        } else {
          nameBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Descriptive text of the additive, e.g. "preservatives".
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField name = 1;</code>
       */
      public Builder mergeName(food.menu.v1.FoodMenu.TextField value) {
        if (nameBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
            name_ != null &&
            name_ != food.menu.v1.FoodMenu.TextField.getDefaultInstance()) {
            getNameBuilder().mergeFrom(value);
          } else {
            name_ = value;
          }
        } else {
          nameBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Descriptive text of the additive, e.g. "preservatives".
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField name = 1;</code>
       */
      public Builder clearName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        name_ = null;
        if (nameBuilder_ != null) {
          nameBuilder_.dispose();
          nameBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Descriptive text of the additive, e.g. "preservatives".
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField name = 1;</code>
       */
      public food.menu.v1.FoodMenu.TextField.Builder getNameBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getNameFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Descriptive text of the additive, e.g. "preservatives".
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField name = 1;</code>
       */
      public food.menu.v1.FoodMenu.TextFieldOrBuilder getNameOrBuilder() {
        if (nameBuilder_ != null) {
          return nameBuilder_.getMessageOrBuilder();
        } else {
          return name_ == null ?
              food.menu.v1.FoodMenu.TextField.getDefaultInstance() : name_;
        }
      }
      /**
       * <pre>
       * Descriptive text of the additive, e.g. "preservatives".
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.TextField name = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder> 
          getNameFieldBuilder() {
        if (nameBuilder_ == null) {
          nameBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              food.menu.v1.FoodMenu.TextField, food.menu.v1.FoodMenu.TextField.Builder, food.menu.v1.FoodMenu.TextFieldOrBuilder>(
                  getName(),
                  getParentForChildren(),
                  isClean());
          name_ = null;
        }
        return nameBuilder_;
      }

      private int containmentLevelCode_ = 0;
      /**
       * <pre>
       * Whether the MenuItem contains, may contain, or is free from this additive.
       * Defaults to contains.
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
       * @return Whether the containmentLevelCode field is set.
       */
      @java.lang.Override public boolean hasContainmentLevelCode() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * Whether the MenuItem contains, may contain, or is free from this additive.
       * Defaults to contains.
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
       * @return The enum numeric value on the wire for containmentLevelCode.
       */
      @java.lang.Override public int getContainmentLevelCodeValue() {
        return containmentLevelCode_;
      }
      /**
       * <pre>
       * Whether the MenuItem contains, may contain, or is free from this additive.
       * Defaults to contains.
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
       * @param value The enum numeric value on the wire for containmentLevelCode to set.
       * @return This builder for chaining.
       */
      public Builder setContainmentLevelCodeValue(int value) {
        containmentLevelCode_ = value;
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Whether the MenuItem contains, may contain, or is free from this additive.
       * Defaults to contains.
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
       * @return The containmentLevelCode.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.ContainmentLevelCode getContainmentLevelCode() {
        food.menu.v1.FoodMenu.ContainmentLevelCode result = food.menu.v1.FoodMenu.ContainmentLevelCode.forNumber(containmentLevelCode_);
        return result == null ? food.menu.v1.FoodMenu.ContainmentLevelCode.UNRECOGNIZED : result;
      }
      /**
       * <pre>
       * Whether the MenuItem contains, may contain, or is free from this additive.
       * Defaults to contains.
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
       * @param value The containmentLevelCode to set.
       * @return This builder for chaining.
       */
      public Builder setContainmentLevelCode(food.menu.v1.FoodMenu.ContainmentLevelCode value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000002;
        containmentLevelCode_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Whether the MenuItem contains, may contain, or is free from this additive.
       * Defaults to contains.
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearContainmentLevelCode() {
        bitField0_ = (bitField0_ & ~0x00000002);
        containmentLevelCode_ = 0;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.Additive)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.Additive)
    private static final food.menu.v1.FoodMenu.Additive DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.Additive();
    }

    public static food.menu.v1.FoodMenu.Additive getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<Additive>
        PARSER = new com.google.protobuf.AbstractParser<Additive>() {
      @java.lang.Override
      public Additive parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<Additive> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<Additive> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.Additive getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface AllergenOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.Allergen)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * Type of allergen.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.AllergenTypeCode allergen_type_code = 1;</code>
     * @return The enum numeric value on the wire for allergenTypeCode.
     */
    int getAllergenTypeCodeValue();
    /**
     * <pre>
     * Type of allergen.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.AllergenTypeCode allergen_type_code = 1;</code>
     * @return The allergenTypeCode.
     */
    food.menu.v1.FoodMenu.AllergenTypeCode getAllergenTypeCode();

    /**
     * <pre>
     * Whether the MenuItem contains, may contain, or is free from this allergen.
     * Defaults to contains.
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
     * @return Whether the containmentLevelCode field is set.
     */
    boolean hasContainmentLevelCode();
    /**
     * <pre>
     * Whether the MenuItem contains, may contain, or is free from this allergen.
     * Defaults to contains.
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
     * @return The enum numeric value on the wire for containmentLevelCode.
     */
    int getContainmentLevelCodeValue();
    /**
     * <pre>
     * Whether the MenuItem contains, may contain, or is free from this allergen.
     * Defaults to contains.
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
     * @return The containmentLevelCode.
     */
    food.menu.v1.FoodMenu.ContainmentLevelCode getContainmentLevelCode();
  }
  /**
   * <pre>
   * Allergen shown to the user on the MenuItem. An allergen relates to qualities
   * of food that causes allergic reactions.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.Allergen}
   */
  public static final class Allergen extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.Allergen)
      AllergenOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Allergen.newBuilder() to construct.
    private Allergen(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Allergen() {
      allergenTypeCode_ = 0;
      containmentLevelCode_ = 0;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new Allergen();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Allergen_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Allergen_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.Allergen.class, food.menu.v1.FoodMenu.Allergen.Builder.class);
    }

    private int bitField0_;
    public static final int ALLERGEN_TYPE_CODE_FIELD_NUMBER = 1;
    private int allergenTypeCode_ = 0;
    /**
     * <pre>
     * Type of allergen.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.AllergenTypeCode allergen_type_code = 1;</code>
     * @return The enum numeric value on the wire for allergenTypeCode.
     */
    @java.lang.Override public int getAllergenTypeCodeValue() {
      return allergenTypeCode_;
    }
    /**
     * <pre>
     * Type of allergen.
     * Required.
     * </pre>
     *
     * <code>.food.menu.v1.AllergenTypeCode allergen_type_code = 1;</code>
     * @return The allergenTypeCode.
     */
    @java.lang.Override public food.menu.v1.FoodMenu.AllergenTypeCode getAllergenTypeCode() {
      food.menu.v1.FoodMenu.AllergenTypeCode result = food.menu.v1.FoodMenu.AllergenTypeCode.forNumber(allergenTypeCode_);
      return result == null ? food.menu.v1.FoodMenu.AllergenTypeCode.UNRECOGNIZED : result;
    }

    public static final int CONTAINMENT_LEVEL_CODE_FIELD_NUMBER = 2;
    private int containmentLevelCode_ = 0;
    /**
     * <pre>
     * Whether the MenuItem contains, may contain, or is free from this allergen.
     * Defaults to contains.
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
     * @return Whether the containmentLevelCode field is set.
     */
    @java.lang.Override public boolean hasContainmentLevelCode() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * Whether the MenuItem contains, may contain, or is free from this allergen.
     * Defaults to contains.
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
     * @return The enum numeric value on the wire for containmentLevelCode.
     */
    @java.lang.Override public int getContainmentLevelCodeValue() {
      return containmentLevelCode_;
    }
    /**
     * <pre>
     * Whether the MenuItem contains, may contain, or is free from this allergen.
     * Defaults to contains.
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
     * @return The containmentLevelCode.
     */
    @java.lang.Override public food.menu.v1.FoodMenu.ContainmentLevelCode getContainmentLevelCode() {
      food.menu.v1.FoodMenu.ContainmentLevelCode result = food.menu.v1.FoodMenu.ContainmentLevelCode.forNumber(containmentLevelCode_);
      return result == null ? food.menu.v1.FoodMenu.ContainmentLevelCode.UNRECOGNIZED : result;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (allergenTypeCode_ != food.menu.v1.FoodMenu.AllergenTypeCode.ALLERGEN_TYPE_CODE_UNSPECIFIED.getNumber()) {
        output.writeEnum(1, allergenTypeCode_);
      }
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(2, containmentLevelCode_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (allergenTypeCode_ != food.menu.v1.FoodMenu.AllergenTypeCode.ALLERGEN_TYPE_CODE_UNSPECIFIED.getNumber()) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, allergenTypeCode_);
      }
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(2, containmentLevelCode_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.Allergen)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.Allergen other = (food.menu.v1.FoodMenu.Allergen) obj;

      if (allergenTypeCode_ != other.allergenTypeCode_) return false;
      if (hasContainmentLevelCode() != other.hasContainmentLevelCode()) return false;
      if (hasContainmentLevelCode()) {
        if (containmentLevelCode_ != other.containmentLevelCode_) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      hash = (37 * hash) + ALLERGEN_TYPE_CODE_FIELD_NUMBER;
      hash = (53 * hash) + allergenTypeCode_;
      if (hasContainmentLevelCode()) {
        hash = (37 * hash) + CONTAINMENT_LEVEL_CODE_FIELD_NUMBER;
        hash = (53 * hash) + containmentLevelCode_;
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.Allergen parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Allergen parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Allergen parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Allergen parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Allergen parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.Allergen parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Allergen parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Allergen parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Allergen parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Allergen parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.Allergen parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.Allergen parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.Allergen prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Allergen shown to the user on the MenuItem. An allergen relates to qualities
     * of food that causes allergic reactions.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.Allergen}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.Allergen)
        food.menu.v1.FoodMenu.AllergenOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Allergen_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Allergen_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.Allergen.class, food.menu.v1.FoodMenu.Allergen.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.Allergen.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        allergenTypeCode_ = 0;
        containmentLevelCode_ = 0;
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_Allergen_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Allergen getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.Allergen.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Allergen build() {
        food.menu.v1.FoodMenu.Allergen result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.Allergen buildPartial() {
        food.menu.v1.FoodMenu.Allergen result = new food.menu.v1.FoodMenu.Allergen(this);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartial0(food.menu.v1.FoodMenu.Allergen result) {
        int from_bitField0_ = bitField0_;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.allergenTypeCode_ = allergenTypeCode_;
        }
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.containmentLevelCode_ = containmentLevelCode_;
          to_bitField0_ |= 0x00000001;
        }
        result.bitField0_ |= to_bitField0_;
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.Allergen) {
          return mergeFrom((food.menu.v1.FoodMenu.Allergen)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.Allergen other) {
        if (other == food.menu.v1.FoodMenu.Allergen.getDefaultInstance()) return this;
        if (other.allergenTypeCode_ != 0) {
          setAllergenTypeCodeValue(other.getAllergenTypeCodeValue());
        }
        if (other.hasContainmentLevelCode()) {
          setContainmentLevelCode(other.getContainmentLevelCode());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                allergenTypeCode_ = input.readEnum();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 16: {
                containmentLevelCode_ = input.readEnum();
                bitField0_ |= 0x00000002;
                break;
              } // case 16
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int allergenTypeCode_ = 0;
      /**
       * <pre>
       * Type of allergen.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.AllergenTypeCode allergen_type_code = 1;</code>
       * @return The enum numeric value on the wire for allergenTypeCode.
       */
      @java.lang.Override public int getAllergenTypeCodeValue() {
        return allergenTypeCode_;
      }
      /**
       * <pre>
       * Type of allergen.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.AllergenTypeCode allergen_type_code = 1;</code>
       * @param value The enum numeric value on the wire for allergenTypeCode to set.
       * @return This builder for chaining.
       */
      public Builder setAllergenTypeCodeValue(int value) {
        allergenTypeCode_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Type of allergen.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.AllergenTypeCode allergen_type_code = 1;</code>
       * @return The allergenTypeCode.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.AllergenTypeCode getAllergenTypeCode() {
        food.menu.v1.FoodMenu.AllergenTypeCode result = food.menu.v1.FoodMenu.AllergenTypeCode.forNumber(allergenTypeCode_);
        return result == null ? food.menu.v1.FoodMenu.AllergenTypeCode.UNRECOGNIZED : result;
      }
      /**
       * <pre>
       * Type of allergen.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.AllergenTypeCode allergen_type_code = 1;</code>
       * @param value The allergenTypeCode to set.
       * @return This builder for chaining.
       */
      public Builder setAllergenTypeCode(food.menu.v1.FoodMenu.AllergenTypeCode value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        allergenTypeCode_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Type of allergen.
       * Required.
       * </pre>
       *
       * <code>.food.menu.v1.AllergenTypeCode allergen_type_code = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearAllergenTypeCode() {
        bitField0_ = (bitField0_ & ~0x00000001);
        allergenTypeCode_ = 0;
        onChanged();
        return this;
      }

      private int containmentLevelCode_ = 0;
      /**
       * <pre>
       * Whether the MenuItem contains, may contain, or is free from this allergen.
       * Defaults to contains.
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
       * @return Whether the containmentLevelCode field is set.
       */
      @java.lang.Override public boolean hasContainmentLevelCode() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * Whether the MenuItem contains, may contain, or is free from this allergen.
       * Defaults to contains.
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
       * @return The enum numeric value on the wire for containmentLevelCode.
       */
      @java.lang.Override public int getContainmentLevelCodeValue() {
        return containmentLevelCode_;
      }
      /**
       * <pre>
       * Whether the MenuItem contains, may contain, or is free from this allergen.
       * Defaults to contains.
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
       * @param value The enum numeric value on the wire for containmentLevelCode to set.
       * @return This builder for chaining.
       */
      public Builder setContainmentLevelCodeValue(int value) {
        containmentLevelCode_ = value;
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Whether the MenuItem contains, may contain, or is free from this allergen.
       * Defaults to contains.
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
       * @return The containmentLevelCode.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.ContainmentLevelCode getContainmentLevelCode() {
        food.menu.v1.FoodMenu.ContainmentLevelCode result = food.menu.v1.FoodMenu.ContainmentLevelCode.forNumber(containmentLevelCode_);
        return result == null ? food.menu.v1.FoodMenu.ContainmentLevelCode.UNRECOGNIZED : result;
      }
      /**
       * <pre>
       * Whether the MenuItem contains, may contain, or is free from this allergen.
       * Defaults to contains.
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
       * @param value The containmentLevelCode to set.
       * @return This builder for chaining.
       */
      public Builder setContainmentLevelCode(food.menu.v1.FoodMenu.ContainmentLevelCode value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000002;
        containmentLevelCode_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Whether the MenuItem contains, may contain, or is free from this allergen.
       * Defaults to contains.
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.ContainmentLevelCode containment_level_code = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearContainmentLevelCode() {
        bitField0_ = (bitField0_ & ~0x00000002);
        containmentLevelCode_ = 0;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.Allergen)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.Allergen)
    private static final food.menu.v1.FoodMenu.Allergen DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.Allergen();
    }

    public static food.menu.v1.FoodMenu.Allergen getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<Allergen>
        PARSER = new com.google.protobuf.AbstractParser<Allergen>() {
      @java.lang.Override
      public Allergen parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<Allergen> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<Allergen> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.Allergen getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface DepositInfoOrBuilder extends
      // @@protoc_insertion_point(interface_extends:food.menu.v1.DepositInfo)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * The deposit strategy to employ, e.g. "reusable".
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.DepositCode deposit_code = 1;</code>
     * @return Whether the depositCode field is set.
     */
    boolean hasDepositCode();
    /**
     * <pre>
     * The deposit strategy to employ, e.g. "reusable".
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.DepositCode deposit_code = 1;</code>
     * @return The enum numeric value on the wire for depositCode.
     */
    int getDepositCodeValue();
    /**
     * <pre>
     * The deposit strategy to employ, e.g. "reusable".
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.DepositCode deposit_code = 1;</code>
     * @return The depositCode.
     */
    food.menu.v1.FoodMenu.DepositCode getDepositCode();

    /**
     * <pre>
     * Value refunded for depositing the item properly.
     * Optional.
     * </pre>
     *
     * <code>.google.type.Money deposit_value = 2;</code>
     * @return Whether the depositValue field is set.
     */
    boolean hasDepositValue();
    /**
     * <pre>
     * Value refunded for depositing the item properly.
     * Optional.
     * </pre>
     *
     * <code>.google.type.Money deposit_value = 2;</code>
     * @return The depositValue.
     */
    com.google.type.Money getDepositValue();
    /**
     * <pre>
     * Value refunded for depositing the item properly.
     * Optional.
     * </pre>
     *
     * <code>.google.type.Money deposit_value = 2;</code>
     */
    com.google.type.MoneyOrBuilder getDepositValueOrBuilder();
  }
  /**
   * <pre>
   * Partner provided deposit info to instruct the user how to deposit a food item
   * or bottle and the value of such deposit.
   * </pre>
   *
   * Protobuf type {@code food.menu.v1.DepositInfo}
   */
  public static final class DepositInfo extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:food.menu.v1.DepositInfo)
      DepositInfoOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use DepositInfo.newBuilder() to construct.
    private DepositInfo(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private DepositInfo() {
      depositCode_ = 0;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new DepositInfo();
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_DepositInfo_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return food.menu.v1.FoodMenu.internal_static_food_menu_v1_DepositInfo_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              food.menu.v1.FoodMenu.DepositInfo.class, food.menu.v1.FoodMenu.DepositInfo.Builder.class);
    }

    private int bitField0_;
    public static final int DEPOSIT_CODE_FIELD_NUMBER = 1;
    private int depositCode_ = 0;
    /**
     * <pre>
     * The deposit strategy to employ, e.g. "reusable".
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.DepositCode deposit_code = 1;</code>
     * @return Whether the depositCode field is set.
     */
    @java.lang.Override public boolean hasDepositCode() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * The deposit strategy to employ, e.g. "reusable".
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.DepositCode deposit_code = 1;</code>
     * @return The enum numeric value on the wire for depositCode.
     */
    @java.lang.Override public int getDepositCodeValue() {
      return depositCode_;
    }
    /**
     * <pre>
     * The deposit strategy to employ, e.g. "reusable".
     * Optional.
     * </pre>
     *
     * <code>optional .food.menu.v1.DepositCode deposit_code = 1;</code>
     * @return The depositCode.
     */
    @java.lang.Override public food.menu.v1.FoodMenu.DepositCode getDepositCode() {
      food.menu.v1.FoodMenu.DepositCode result = food.menu.v1.FoodMenu.DepositCode.forNumber(depositCode_);
      return result == null ? food.menu.v1.FoodMenu.DepositCode.UNRECOGNIZED : result;
    }

    public static final int DEPOSIT_VALUE_FIELD_NUMBER = 2;
    private com.google.type.Money depositValue_;
    /**
     * <pre>
     * Value refunded for depositing the item properly.
     * Optional.
     * </pre>
     *
     * <code>.google.type.Money deposit_value = 2;</code>
     * @return Whether the depositValue field is set.
     */
    @java.lang.Override
    public boolean hasDepositValue() {
      return depositValue_ != null;
    }
    /**
     * <pre>
     * Value refunded for depositing the item properly.
     * Optional.
     * </pre>
     *
     * <code>.google.type.Money deposit_value = 2;</code>
     * @return The depositValue.
     */
    @java.lang.Override
    public com.google.type.Money getDepositValue() {
      return depositValue_ == null ? com.google.type.Money.getDefaultInstance() : depositValue_;
    }
    /**
     * <pre>
     * Value refunded for depositing the item properly.
     * Optional.
     * </pre>
     *
     * <code>.google.type.Money deposit_value = 2;</code>
     */
    @java.lang.Override
    public com.google.type.MoneyOrBuilder getDepositValueOrBuilder() {
      return depositValue_ == null ? com.google.type.Money.getDefaultInstance() : depositValue_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, depositCode_);
      }
      if (depositValue_ != null) {
        output.writeMessage(2, getDepositValue());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, depositCode_);
      }
      if (depositValue_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getDepositValue());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof food.menu.v1.FoodMenu.DepositInfo)) {
        return super.equals(obj);
      }
      food.menu.v1.FoodMenu.DepositInfo other = (food.menu.v1.FoodMenu.DepositInfo) obj;

      if (hasDepositCode() != other.hasDepositCode()) return false;
      if (hasDepositCode()) {
        if (depositCode_ != other.depositCode_) return false;
      }
      if (hasDepositValue() != other.hasDepositValue()) return false;
      if (hasDepositValue()) {
        if (!getDepositValue()
            .equals(other.getDepositValue())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasDepositCode()) {
        hash = (37 * hash) + DEPOSIT_CODE_FIELD_NUMBER;
        hash = (53 * hash) + depositCode_;
      }
      if (hasDepositValue()) {
        hash = (37 * hash) + DEPOSIT_VALUE_FIELD_NUMBER;
        hash = (53 * hash) + getDepositValue().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static food.menu.v1.FoodMenu.DepositInfo parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.DepositInfo parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.DepositInfo parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.DepositInfo parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.DepositInfo parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static food.menu.v1.FoodMenu.DepositInfo parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.DepositInfo parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.DepositInfo parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.DepositInfo parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.DepositInfo parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static food.menu.v1.FoodMenu.DepositInfo parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static food.menu.v1.FoodMenu.DepositInfo parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(food.menu.v1.FoodMenu.DepositInfo prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Partner provided deposit info to instruct the user how to deposit a food item
     * or bottle and the value of such deposit.
     * </pre>
     *
     * Protobuf type {@code food.menu.v1.DepositInfo}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:food.menu.v1.DepositInfo)
        food.menu.v1.FoodMenu.DepositInfoOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_DepositInfo_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_DepositInfo_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                food.menu.v1.FoodMenu.DepositInfo.class, food.menu.v1.FoodMenu.DepositInfo.Builder.class);
      }

      // Construct using food.menu.v1.FoodMenu.DepositInfo.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        bitField0_ = 0;
        depositCode_ = 0;
        depositValue_ = null;
        if (depositValueBuilder_ != null) {
          depositValueBuilder_.dispose();
          depositValueBuilder_ = null;
        }
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return food.menu.v1.FoodMenu.internal_static_food_menu_v1_DepositInfo_descriptor;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.DepositInfo getDefaultInstanceForType() {
        return food.menu.v1.FoodMenu.DepositInfo.getDefaultInstance();
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.DepositInfo build() {
        food.menu.v1.FoodMenu.DepositInfo result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public food.menu.v1.FoodMenu.DepositInfo buildPartial() {
        food.menu.v1.FoodMenu.DepositInfo result = new food.menu.v1.FoodMenu.DepositInfo(this);
        if (bitField0_ != 0) { buildPartial0(result); }
        onBuilt();
        return result;
      }

      private void buildPartial0(food.menu.v1.FoodMenu.DepositInfo result) {
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.depositCode_ = depositCode_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.depositValue_ = depositValueBuilder_ == null
              ? depositValue_
              : depositValueBuilder_.build();
        }
        result.bitField0_ |= to_bitField0_;
      }

      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof food.menu.v1.FoodMenu.DepositInfo) {
          return mergeFrom((food.menu.v1.FoodMenu.DepositInfo)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(food.menu.v1.FoodMenu.DepositInfo other) {
        if (other == food.menu.v1.FoodMenu.DepositInfo.getDefaultInstance()) return this;
        if (other.hasDepositCode()) {
          setDepositCode(other.getDepositCode());
        }
        if (other.hasDepositValue()) {
          mergeDepositValue(other.getDepositValue());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                depositCode_ = input.readEnum();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 18: {
                input.readMessage(
                    getDepositValueFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int depositCode_ = 0;
      /**
       * <pre>
       * The deposit strategy to employ, e.g. "reusable".
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.DepositCode deposit_code = 1;</code>
       * @return Whether the depositCode field is set.
       */
      @java.lang.Override public boolean hasDepositCode() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * The deposit strategy to employ, e.g. "reusable".
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.DepositCode deposit_code = 1;</code>
       * @return The enum numeric value on the wire for depositCode.
       */
      @java.lang.Override public int getDepositCodeValue() {
        return depositCode_;
      }
      /**
       * <pre>
       * The deposit strategy to employ, e.g. "reusable".
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.DepositCode deposit_code = 1;</code>
       * @param value The enum numeric value on the wire for depositCode to set.
       * @return This builder for chaining.
       */
      public Builder setDepositCodeValue(int value) {
        depositCode_ = value;
        bitField0_ |= 0x00000001;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The deposit strategy to employ, e.g. "reusable".
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.DepositCode deposit_code = 1;</code>
       * @return The depositCode.
       */
      @java.lang.Override
      public food.menu.v1.FoodMenu.DepositCode getDepositCode() {
        food.menu.v1.FoodMenu.DepositCode result = food.menu.v1.FoodMenu.DepositCode.forNumber(depositCode_);
        return result == null ? food.menu.v1.FoodMenu.DepositCode.UNRECOGNIZED : result;
      }
      /**
       * <pre>
       * The deposit strategy to employ, e.g. "reusable".
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.DepositCode deposit_code = 1;</code>
       * @param value The depositCode to set.
       * @return This builder for chaining.
       */
      public Builder setDepositCode(food.menu.v1.FoodMenu.DepositCode value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        depositCode_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The deposit strategy to employ, e.g. "reusable".
       * Optional.
       * </pre>
       *
       * <code>optional .food.menu.v1.DepositCode deposit_code = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearDepositCode() {
        bitField0_ = (bitField0_ & ~0x00000001);
        depositCode_ = 0;
        onChanged();
        return this;
      }

      private com.google.type.Money depositValue_;
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.type.Money, com.google.type.Money.Builder, com.google.type.MoneyOrBuilder> depositValueBuilder_;
      /**
       * <pre>
       * Value refunded for depositing the item properly.
       * Optional.
       * </pre>
       *
       * <code>.google.type.Money deposit_value = 2;</code>
       * @return Whether the depositValue field is set.
       */
      public boolean hasDepositValue() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * Value refunded for depositing the item properly.
       * Optional.
       * </pre>
       *
       * <code>.google.type.Money deposit_value = 2;</code>
       * @return The depositValue.
       */
      public com.google.type.Money getDepositValue() {
        if (depositValueBuilder_ == null) {
          return depositValue_ == null ? com.google.type.Money.getDefaultInstance() : depositValue_;
        } else {
          return depositValueBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Value refunded for depositing the item properly.
       * Optional.
       * </pre>
       *
       * <code>.google.type.Money deposit_value = 2;</code>
       */
      public Builder setDepositValue(com.google.type.Money value) {
        if (depositValueBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          depositValue_ = value;
        } else {
          depositValueBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Value refunded for depositing the item properly.
       * Optional.
       * </pre>
       *
       * <code>.google.type.Money deposit_value = 2;</code>
       */
      public Builder setDepositValue(
          com.google.type.Money.Builder builderForValue) {
        if (depositValueBuilder_ == null) {
          depositValue_ = builderForValue.build();
        } else {
          depositValueBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Value refunded for depositing the item properly.
       * Optional.
       * </pre>
       *
       * <code>.google.type.Money deposit_value = 2;</code>
       */
      public Builder mergeDepositValue(com.google.type.Money value) {
        if (depositValueBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
            depositValue_ != null &&
            depositValue_ != com.google.type.Money.getDefaultInstance()) {
            getDepositValueBuilder().mergeFrom(value);
          } else {
            depositValue_ = value;
          }
        } else {
          depositValueBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Value refunded for depositing the item properly.
       * Optional.
       * </pre>
       *
       * <code>.google.type.Money deposit_value = 2;</code>
       */
      public Builder clearDepositValue() {
        bitField0_ = (bitField0_ & ~0x00000002);
        depositValue_ = null;
        if (depositValueBuilder_ != null) {
          depositValueBuilder_.dispose();
          depositValueBuilder_ = null;
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Value refunded for depositing the item properly.
       * Optional.
       * </pre>
       *
       * <code>.google.type.Money deposit_value = 2;</code>
       */
      public com.google.type.Money.Builder getDepositValueBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getDepositValueFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Value refunded for depositing the item properly.
       * Optional.
       * </pre>
       *
       * <code>.google.type.Money deposit_value = 2;</code>
       */
      public com.google.type.MoneyOrBuilder getDepositValueOrBuilder() {
        if (depositValueBuilder_ != null) {
          return depositValueBuilder_.getMessageOrBuilder();
        } else {
          return depositValue_ == null ?
              com.google.type.Money.getDefaultInstance() : depositValue_;
        }
      }
      /**
       * <pre>
       * Value refunded for depositing the item properly.
       * Optional.
       * </pre>
       *
       * <code>.google.type.Money deposit_value = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.type.Money, com.google.type.Money.Builder, com.google.type.MoneyOrBuilder> 
          getDepositValueFieldBuilder() {
        if (depositValueBuilder_ == null) {
          depositValueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              com.google.type.Money, com.google.type.Money.Builder, com.google.type.MoneyOrBuilder>(
                  getDepositValue(),
                  getParentForChildren(),
                  isClean());
          depositValue_ = null;
        }
        return depositValueBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:food.menu.v1.DepositInfo)
    }

    // @@protoc_insertion_point(class_scope:food.menu.v1.DepositInfo)
    private static final food.menu.v1.FoodMenu.DepositInfo DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new food.menu.v1.FoodMenu.DepositInfo();
    }

    public static food.menu.v1.FoodMenu.DepositInfo getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<DepositInfo>
        PARSER = new com.google.protobuf.AbstractParser<DepositInfo>() {
      @java.lang.Override
      public DepositInfo parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<DepositInfo> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<DepositInfo> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public food.menu.v1.FoodMenu.DepositInfo getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_FoodMenuFeed_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_FoodMenuFeed_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_MenuComponent_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_MenuComponent_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_Menu_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_Menu_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_MenuSection_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_MenuSection_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_MenuItem_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_MenuItem_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_MenuItem_MenuItemOptionSet_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_MenuItem_MenuItemOptionSet_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_MenuItemOption_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_MenuItemOption_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_MenuItemAttributes_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_MenuItemAttributes_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_OfferSet_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_OfferSet_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_Offer_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_Offer_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_Disclaimer_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_Disclaimer_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_TextField_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_TextField_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_Image_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_Image_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_MenuItemOptionProperty_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_MenuItemOptionProperty_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_NutritionInformation_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_NutritionInformation_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_NutritionInformation_NutritionValue_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_NutritionInformation_NutritionValue_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_NutritionInformation_NutritionValue_Range_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_NutritionInformation_NutritionValue_Range_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_Additive_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_Additive_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_Allergen_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_Allergen_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_food_menu_v1_DepositInfo_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_food_menu_v1_DepositInfo_fieldAccessorTable;

  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static  com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    java.lang.String[] descriptorData = {
      "\n\017food_menu.proto\022\014food.menu.v1\032\037google/" +
      "protobuf/timestamp.proto\032\024localized_text" +
      ".proto\032\013money.proto\"9\n\014FoodMenuFeed\022)\n\004d" +
      "ata\030\001 \003(\0132\033.food.menu.v1.MenuComponent\"\301" +
      "\001\n\rMenuComponent\022\"\n\004menu\030\001 \001(\0132\022.food.me" +
      "nu.v1.MenuH\000\022,\n\007section\030\002 \001(\0132\031.food.men" +
      "u.v1.MenuSectionH\000\022&\n\004item\030\003 \001(\0132\026.food." +
      "menu.v1.MenuItemH\000\022.\n\006option\030\004 \001(\0132\034.foo" +
      "d.menu.v1.MenuItemOptionH\000B\006\n\004type\"\214\002\n\004M" +
      "enu\022\017\n\007menu_id\030\001 \001(\t\022\024\n\014merchant_ids\030\002 \003" +
      "(\t\022-\n\014display_name\030\003 \001(\0132\027.food.menu.v1." +
      "TextField\022\020\n\010language\030\004 \001(\t\022,\n\ndisclaime" +
      "r\030\005 \001(\0132\030.food.menu.v1.Disclaimer\022\025\n\rmen" +
      "u_item_ids\030\006 \003(\t\022\030\n\020menu_section_ids\030\007 \003" +
      "(\t\022=\n\031last_merchant_update_time\030\010 \001(\0132\032." +
      "google.protobuf.Timestamp\"\331\001\n\013MenuSectio" +
      "n\022\027\n\017menu_section_id\030\001 \001(\t\022-\n\014display_na" +
      "me\030\002 \001(\0132\027.food.menu.v1.TextField\022,\n\013des" +
      "cription\030\003 \001(\0132\027.food.menu.v1.TextField\022" +
      "#\n\006images\030\004 \003(\0132\023.food.menu.v1.Image\022\025\n\r" +
      "menu_item_ids\030\006 \003(\t\022\030\n\020menu_section_ids\030" +
      "\007 \003(\t\"\222\003\n\010MenuItem\022\024\n\014menu_item_id\030\001 \001(\t" +
      "\022-\n\014display_name\030\002 \001(\0132\027.food.menu.v1.Te" +
      "xtField\022,\n\013description\030\003 \001(\0132\027.food.menu" +
      ".v1.TextField\022#\n\006images\030\004 \003(\0132\023.food.men" +
      "u.v1.Image\022+\n\toffer_set\030\006 \001(\0132\026.food.men" +
      "u.v1.OfferSetH\000\022H\n\024menu_item_option_set\030" +
      "\007 \001(\0132(.food.menu.v1.MenuItem.MenuItemOp" +
      "tionSetH\000\0229\n\017item_attributes\030\010 \001(\0132 .foo" +
      "d.menu.v1.MenuItemAttributes\0321\n\021MenuItem" +
      "OptionSet\022\034\n\024menu_item_option_ids\030\001 \003(\tB" +
      "\t\n\007pricing\"\310\001\n\016MenuItemOption\022\033\n\023menu_it" +
      "em_option_id\030\t \001(\t\0223\n\005value\030\002 \001(\0132$.food" +
      ".menu.v1.MenuItemOptionProperty\022)\n\toffer" +
      "_set\030\004 \001(\0132\026.food.menu.v1.OfferSet\0229\n\017it" +
      "em_attributes\030\005 \001(\0132 .food.menu.v1.MenuI" +
      "temAttributes\"\330\002\n\022MenuItemAttributes\022\037\n\022" +
      "number_of_servings\030\001 \001(\005H\000\210\001\001\022A\n\025nutriti" +
      "on_information\030\002 \001(\0132\".food.menu.v1.Nutr" +
      "itionInformation\0228\n\016suitable_diets\030\003 \003(\016" +
      "2 .food.menu.v1.DietaryRestriction\022(\n\010ad" +
      "ditive\030\004 \003(\0132\026.food.menu.v1.Additive\022(\n\010" +
      "allergen\030\005 \003(\0132\026.food.menu.v1.Allergen\0229" +
      "\n\026packaging_deposit_info\030\006 \001(\0132\031.food.me" +
      "nu.v1.DepositInfoB\025\n\023_number_of_servings" +
      "\"/\n\010OfferSet\022#\n\006offers\030\001 \003(\0132\023.food.menu" +
      ".v1.Offer\"*\n\005Offer\022!\n\005price\030\001 \001(\0132\022.goog" +
      "le.type.Money\"@\n\nDisclaimer\022%\n\004text\030\001 \001(" +
      "\0132\027.food.menu.v1.TextField\022\013\n\003uri\030\002 \001(\t\"" +
      "5\n\tTextField\022(\n\004text\030\001 \003(\0132\032.google.type" +
      ".LocalizedText\"\024\n\005Image\022\013\n\003uri\030\001 \001(\t\"\243\003\n" +
      "\026MenuItemOptionProperty\022H\n\rproperty_type" +
      "\030\001 \001(\01621.food.menu.v1.MenuItemOptionProp" +
      "erty.PropertyType\022J\n\014property_val\030\002 \001(\0162" +
      "2.food.menu.v1.MenuItemOptionProperty.Pr" +
      "opertyValueH\000\022+\n\010text_val\030\003 \001(\0132\027.food.m" +
      "enu.v1.TextFieldH\000\"O\n\014PropertyType\022\031\n\025UN" +
      "KNOWN_PROPERTY_TYPE\020\000\022\n\n\006OPTION\020\001\022\010\n\004SIZ" +
      "E\020\002\022\016\n\nPIZZA_SIDE\020\003\"l\n\rPropertyValue\022\032\n\026" +
      "UNKNOWN_PROPERTY_VALUE\020\000\022\023\n\017PIZZA_SIDE_L" +
      "EFT\020\001\022\024\n\020PIZZA_SIDE_RIGHT\020\002\022\024\n\020PIZZA_SID" +
      "E_WHOLE\020\003B\007\n\005value\"\311\003\n\024NutritionInformat" +
      "ion\022A\n\006energy\030\001 \001(\01321.food.menu.v1.Nutri" +
      "tionInformation.NutritionValue\022I\n\016sodium" +
      "_content\030\002 \001(\01321.food.menu.v1.NutritionI" +
      "nformation.NutritionValue\022\031\n\014serving_siz" +
      "e\030\003 \001(\005H\000\210\001\001\022,\n\013description\030\004 \001(\0132\027.food" +
      ".menu.v1.TextField\032\310\001\n\016NutritionValue\022\020\n" +
      "\006amount\030\001 \001(\001H\000\022H\n\005range\030\003 \001(\01327.food.me" +
      "nu.v1.NutritionInformation.NutritionValu" +
      "e.RangeH\000\022.\n\004unit\030\002 \001(\0162 .food.menu.v1.N" +
      "utritionValueUnit\032!\n\005Range\022\013\n\003min\030\001 \001(\001\022" +
      "\013\n\003max\030\002 \001(\001B\007\n\005valueB\017\n\r_serving_size\"\225" +
      "\001\n\010Additive\022%\n\004name\030\001 \001(\0132\027.food.menu.v1" +
      ".TextField\022G\n\026containment_level_code\030\002 \001" +
      "(\0162\".food.menu.v1.ContainmentLevelCodeH\000" +
      "\210\001\001B\031\n\027_containment_level_code\"\252\001\n\010Aller" +
      "gen\022:\n\022allergen_type_code\030\001 \001(\0162\036.food.m" +
      "enu.v1.AllergenTypeCode\022G\n\026containment_l" +
      "evel_code\030\002 \001(\0162\".food.menu.v1.Containme" +
      "ntLevelCodeH\000\210\001\001B\031\n\027_containment_level_c" +
      "ode\"\177\n\013DepositInfo\0224\n\014deposit_code\030\001 \001(\016" +
      "2\031.food.menu.v1.DepositCodeH\000\210\001\001\022)\n\rdepo" +
      "sit_value\030\002 \001(\0132\022.google.type.MoneyB\017\n\r_" +
      "deposit_code*\372\001\n\022DietaryRestriction\022\024\n\020D" +
      "IET_UNSPECIFIED\020\000\022\021\n\rDIET_DIABETIC\020\001\022\024\n\020" +
      "DIET_GLUTEN_FREE\020\002\022\016\n\nDIET_HALAL\020\003\022\016\n\nDI" +
      "ET_HINDU\020\004\022\017\n\013DIET_KOSHER\020\005\022\024\n\020DIET_LOW_" +
      "CALORIE\020\006\022\020\n\014DIET_LOW_FAT\020\007\022\024\n\020DIET_LOW_" +
      "LACTOSE\020\010\022\021\n\rDIET_LOW_SALT\020\t\022\016\n\nDIET_VEG" +
      "AN\020\n\022\023\n\017DIET_VEGETARIAN\020\013*\207\022\n\020AllergenTy" +
      "peCode\022\"\n\036ALLERGEN_TYPE_CODE_UNSPECIFIED" +
      "\020\000\022\036\n\032ALLERGEN_TYPE_CODE_ALMONDS\020\001\022-\n)AL" +
      "LERGEN_TYPE_CODE_ALPHA_ISOMETHYL_IONONE\020" +
      "\002\022\036\n\032ALLERGEN_TYPE_CODE_ALCOHOL\020\003\022$\n ALL" +
      "ERGEN_TYPE_CODE_AMYL_CINNAMAL\020\004\022$\n ALLER" +
      "GEN_TYPE_CODE_ANISE_ALCOHOL\020\005\022\035\n\031ALLERGE" +
      "N_TYPE_CODE_BARLEY\020\006\022%\n!ALLERGEN_TYPE_CO" +
      "DE_BENZYL_ALCOHOL\020\007\022&\n\"ALLERGEN_TYPE_COD" +
      "E_BENZYL_BENZOATE\020\010\022\'\n#ALLERGEN_TYPE_COD" +
      "E_BENZYL_CINNAMATE\020\t\022(\n$ALLERGEN_TYPE_CO" +
      "DE_BENZYL_SALICYLATE\020\n\022\"\n\036ALLERGEN_TYPE_" +
      "CODE_BRAZIL_NUTS\020\013\0223\n/ALLERGEN_TYPE_CODE" +
      "_BUTYLPHENYL_METHYLPROPIONATE\020\014\022\036\n\032ALLER" +
      "GEN_TYPE_CODE_CARROTS\020\r\022\"\n\036ALLERGEN_TYPE" +
      "_CODE_CASHEW_NUTS\020\016\022\035\n\031ALLERGEN_TYPE_COD" +
      "E_CELERY\020\017\0220\n,ALLERGEN_TYPE_CODE_CEREALS" +
      "_CONTAINING_GLUTEN\020\020\022\037\n\033ALLERGEN_TYPE_CO" +
      "DE_CINNAMAL\020\021\022\'\n#ALLERGEN_TYPE_CODE_CINN" +
      "AMYL_ALCOHOL\020\022\022\035\n\031ALLERGEN_TYPE_CODE_CIT" +
      "RAL\020\023\022\"\n\036ALLERGEN_TYPE_CODE_CITRONELLOL\020" +
      "\024\022\034\n\030ALLERGEN_TYPE_CODE_COCOA\020\025\022 \n\034ALLER" +
      "GEN_TYPE_CODE_CORIANDER\020\026\022\033\n\027ALLERGEN_TY" +
      "PE_CODE_CORN\020\027\022\037\n\033ALLERGEN_TYPE_CODE_COU" +
      "MARIN\020\030\022\"\n\036ALLERGEN_TYPE_CODE_CRUSTACEAN" +
      "S\020\031\022\033\n\027ALLERGEN_TYPE_CODE_EGGS\020\032\022\036\n\032ALLE" +
      "RGEN_TYPE_CODE_EUGENOL\020\033\022)\n%ALLERGEN_TYP" +
      "E_CODE_EVERNIA_FURFURACEA\020\034\022(\n$ALLERGEN_" +
      "TYPE_CODE_EVERNIA_PRUNASTRI\020\035\022\037\n\033ALLERGE" +
      "N_TYPE_CODE_FARNESOL\020\036\022\033\n\027ALLERGEN_TYPE_" +
      "CODE_FISH\020\037\022\037\n\033ALLERGEN_TYPE_CODE_GERANI" +
      "OL\020 \022\035\n\031ALLERGEN_TYPE_CODE_GLUTEN\020!\022 \n\034A" +
      "LLERGEN_TYPE_CODE_HAZELNUTS\020\"\022%\n!ALLERGE" +
      "N_TYPE_CODE_HEXYL_CINNAMAL\020#\022)\n%ALLERGEN" +
      "_TYPE_CODE_HYDROXYCITRONELLAL\020$\022]\nYALLER" +
      "GEN_TYPE_CODE_HYDROXYISOHEXYL_3_CYCLOHEX" +
      "ENE_CARBOXALDEHYDE_ISOEUGENOL_LIMONENE_L" +
      "INAL\020%\022\034\n\030ALLERGEN_TYPE_CODE_KAMUT\020&\022\036\n\032" +
      "ALLERGEN_TYPE_CODE_LACTOSE\020\'\022\035\n\031ALLERGEN" +
      "_TYPE_CODE_LUPINE\020(\022%\n!ALLERGEN_TYPE_COD" +
      "E_MACADAMIA_NUTS\020)\022)\n%ALLERGEN_TYPE_CODE" +
      "_METHYL_2_OCTYNOATE\020*\022\033\n\027ALLERGEN_TYPE_C" +
      "ODE_MILK\020+\022\037\n\033ALLERGEN_TYPE_CODE_MOLLUSC" +
      "S\020,\022\036\n\032ALLERGEN_TYPE_CODE_MUSTARD\020-\022,\n(A" +
      "LLERGEN_TYPE_CODE_NO_DECLARED_ALLERGENS\020" +
      ".\022\032\n\026ALLERGEN_TYPE_CODE_OAT\020/\022\036\n\032ALLERGE" +
      "N_TYPE_CODE_PEANUTS\0200\022\033\n\027ALLERGEN_TYPE_C" +
      "ODE_PEAS\0201\022!\n\035ALLERGEN_TYPE_CODE_PECAN_N" +
      "UTS\0202\022!\n\035ALLERGEN_TYPE_CODE_PISTACHIOS\0203" +
      "\022!\n\035ALLERGEN_TYPE_CODE_POD_FRUITS\0204\022&\n\"A" +
      "LLERGEN_TYPE_CODE_QUEENSLAND_NUTS\0205\022\032\n\026A" +
      "LLERGEN_TYPE_CODE_RYE\0206\022#\n\037ALLERGEN_TYPE" +
      "_CODE_SESAME_SEEDS\0207\022\037\n\033ALLERGEN_TYPE_CO" +
      "DE_SOYBEANS\0208\022\034\n\030ALLERGEN_TYPE_CODE_SPEL" +
      "T\0209\022&\n\"ALLERGEN_TYPE_CODE_SULPHUR_DIOXID" +
      "E\020:\022 \n\034ALLERGEN_TYPE_CODE_TREE_NUTS\020;\022&\n" +
      "\"ALLERGEN_TYPE_CODE_TREE_NUT_TRACES\020<\022\036\n" +
      "\032ALLERGEN_TYPE_CODE_WALNUTS\020=\022\034\n\030ALLERGE" +
      "N_TYPE_CODE_WHEAT\020>*\217\001\n\022NutritionValueUn" +
      "it\022$\n NUTRITION_VALUE_UNIT_UNSPECIFIED\020\000" +
      "\022\023\n\017ENERGY_CALORIES\020\001\022\025\n\021ENERGY_KILOJOUL" +
      "ES\020\002\022\025\n\021WEIGHT_MILLIGRAMS\020\003\022\020\n\014WEIGHT_GR" +
      "AMS\020\004*\270\001\n\024ContainmentLevelCode\022&\n\"CONTAI" +
      "NMENT_LEVEL_CODE_UNSPECIFIED\020\000\022#\n\037CONTAI" +
      "NMENT_LEVEL_CODE_CONTAINS\020\001\022+\n\'CONTAINME" +
      "NT_LEVEL_CODE_DOES_NOT_CONTAIN\020\002\022&\n\"CONT" +
      "AINMENT_LEVEL_CODE_MAY_CONTAIN\020\003*c\n\013Depo" +
      "sitCode\022\034\n\030DEPOSIT_CODE_UNSPECIFIED\020\000\022\031\n" +
      "\025DEPOSIT_CODE_REUSABLE\020\001\022\033\n\027DEPOSIT_CODE" +
      "_RECYCLABLE\020\002b\006proto3"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
          com.google.protobuf.TimestampProto.getDescriptor(),
          com.google.type.LocalizedTextProto.getDescriptor(),
          com.google.type.MoneyProto.getDescriptor(),
        });
    internal_static_food_menu_v1_FoodMenuFeed_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_food_menu_v1_FoodMenuFeed_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_FoodMenuFeed_descriptor,
        new java.lang.String[] { "Data", });
    internal_static_food_menu_v1_MenuComponent_descriptor =
      getDescriptor().getMessageTypes().get(1);
    internal_static_food_menu_v1_MenuComponent_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_MenuComponent_descriptor,
        new java.lang.String[] { "Menu", "Section", "Item", "Option", "Type", });
    internal_static_food_menu_v1_Menu_descriptor =
      getDescriptor().getMessageTypes().get(2);
    internal_static_food_menu_v1_Menu_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_Menu_descriptor,
        new java.lang.String[] { "MenuId", "MerchantIds", "DisplayName", "Language", "Disclaimer", "MenuItemIds", "MenuSectionIds", "LastMerchantUpdateTime", });
    internal_static_food_menu_v1_MenuSection_descriptor =
      getDescriptor().getMessageTypes().get(3);
    internal_static_food_menu_v1_MenuSection_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_MenuSection_descriptor,
        new java.lang.String[] { "MenuSectionId", "DisplayName", "Description", "Images", "MenuItemIds", "MenuSectionIds", });
    internal_static_food_menu_v1_MenuItem_descriptor =
      getDescriptor().getMessageTypes().get(4);
    internal_static_food_menu_v1_MenuItem_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_MenuItem_descriptor,
        new java.lang.String[] { "MenuItemId", "DisplayName", "Description", "Images", "OfferSet", "MenuItemOptionSet", "ItemAttributes", "Pricing", });
    internal_static_food_menu_v1_MenuItem_MenuItemOptionSet_descriptor =
      internal_static_food_menu_v1_MenuItem_descriptor.getNestedTypes().get(0);
    internal_static_food_menu_v1_MenuItem_MenuItemOptionSet_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_MenuItem_MenuItemOptionSet_descriptor,
        new java.lang.String[] { "MenuItemOptionIds", });
    internal_static_food_menu_v1_MenuItemOption_descriptor =
      getDescriptor().getMessageTypes().get(5);
    internal_static_food_menu_v1_MenuItemOption_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_MenuItemOption_descriptor,
        new java.lang.String[] { "MenuItemOptionId", "Value", "OfferSet", "ItemAttributes", });
    internal_static_food_menu_v1_MenuItemAttributes_descriptor =
      getDescriptor().getMessageTypes().get(6);
    internal_static_food_menu_v1_MenuItemAttributes_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_MenuItemAttributes_descriptor,
        new java.lang.String[] { "NumberOfServings", "NutritionInformation", "SuitableDiets", "Additive", "Allergen", "PackagingDepositInfo", "NumberOfServings", });
    internal_static_food_menu_v1_OfferSet_descriptor =
      getDescriptor().getMessageTypes().get(7);
    internal_static_food_menu_v1_OfferSet_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_OfferSet_descriptor,
        new java.lang.String[] { "Offers", });
    internal_static_food_menu_v1_Offer_descriptor =
      getDescriptor().getMessageTypes().get(8);
    internal_static_food_menu_v1_Offer_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_Offer_descriptor,
        new java.lang.String[] { "Price", });
    internal_static_food_menu_v1_Disclaimer_descriptor =
      getDescriptor().getMessageTypes().get(9);
    internal_static_food_menu_v1_Disclaimer_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_Disclaimer_descriptor,
        new java.lang.String[] { "Text", "Uri", });
    internal_static_food_menu_v1_TextField_descriptor =
      getDescriptor().getMessageTypes().get(10);
    internal_static_food_menu_v1_TextField_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_TextField_descriptor,
        new java.lang.String[] { "Text", });
    internal_static_food_menu_v1_Image_descriptor =
      getDescriptor().getMessageTypes().get(11);
    internal_static_food_menu_v1_Image_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_Image_descriptor,
        new java.lang.String[] { "Uri", });
    internal_static_food_menu_v1_MenuItemOptionProperty_descriptor =
      getDescriptor().getMessageTypes().get(12);
    internal_static_food_menu_v1_MenuItemOptionProperty_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_MenuItemOptionProperty_descriptor,
        new java.lang.String[] { "PropertyType", "PropertyVal", "TextVal", "Value", });
    internal_static_food_menu_v1_NutritionInformation_descriptor =
      getDescriptor().getMessageTypes().get(13);
    internal_static_food_menu_v1_NutritionInformation_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_NutritionInformation_descriptor,
        new java.lang.String[] { "Energy", "SodiumContent", "ServingSize", "Description", "ServingSize", });
    internal_static_food_menu_v1_NutritionInformation_NutritionValue_descriptor =
      internal_static_food_menu_v1_NutritionInformation_descriptor.getNestedTypes().get(0);
    internal_static_food_menu_v1_NutritionInformation_NutritionValue_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_NutritionInformation_NutritionValue_descriptor,
        new java.lang.String[] { "Amount", "Range", "Unit", "Value", });
    internal_static_food_menu_v1_NutritionInformation_NutritionValue_Range_descriptor =
      internal_static_food_menu_v1_NutritionInformation_NutritionValue_descriptor.getNestedTypes().get(0);
    internal_static_food_menu_v1_NutritionInformation_NutritionValue_Range_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_NutritionInformation_NutritionValue_Range_descriptor,
        new java.lang.String[] { "Min", "Max", });
    internal_static_food_menu_v1_Additive_descriptor =
      getDescriptor().getMessageTypes().get(14);
    internal_static_food_menu_v1_Additive_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_Additive_descriptor,
        new java.lang.String[] { "Name", "ContainmentLevelCode", "ContainmentLevelCode", });
    internal_static_food_menu_v1_Allergen_descriptor =
      getDescriptor().getMessageTypes().get(15);
    internal_static_food_menu_v1_Allergen_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_Allergen_descriptor,
        new java.lang.String[] { "AllergenTypeCode", "ContainmentLevelCode", "ContainmentLevelCode", });
    internal_static_food_menu_v1_DepositInfo_descriptor =
      getDescriptor().getMessageTypes().get(16);
    internal_static_food_menu_v1_DepositInfo_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_food_menu_v1_DepositInfo_descriptor,
        new java.lang.String[] { "DepositCode", "DepositValue", "DepositCode", });
    com.google.protobuf.TimestampProto.getDescriptor();
    com.google.type.LocalizedTextProto.getDescriptor();
    com.google.type.MoneyProto.getDescriptor();
  }

  // @@protoc_insertion_point(outer_class_scope)
}
