diff --git a/menu-feed/go/app b/menu-feed/go/app
new file mode 100755
index 0000000..eb6dfb6
--- /dev/null
+++ b/menu-feed/go/app
Binary files differ
diff --git a/menu-feed/go/feed.go b/menu-feed/go/feed.go
new file mode 100644
index 0000000..2f5e0f7
--- /dev/null
+++ b/menu-feed/go/feed.go
@@ -0,0 +1,135 @@
+/*
+Menu feed example used in
+https://developers.google.com/maps-booking/verticals/dining/guides/tutorials/tutorial-menu-feed-protos#go.
+*
+*/
+package main
+
+import (
+	pb "feed/app/generated/food/menu/v1/proto"
+	"fmt"
+
+	localized_text "google.golang.org/genproto/googleapis/type/localized_text"
+	money "google.golang.org/genproto/googleapis/type/money"
+	"google.golang.org/protobuf/encoding/protojson"
+	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
+)
+
+func main() {
+
+	//create a menu component
+	menu := &pb.Menu{
+		MenuId:      "menu1",
+		MerchantIds: []string{"dining-1"},
+		DisplayName: &pb.TextField{
+			Text: []*localized_text.LocalizedText{{
+				Text:         "Menu",
+				LanguageCode: "en-us",
+			}},
+		},
+		Language: "en-us",
+		LastMerchantUpdateTime: &timestamppb.Timestamp{
+			Seconds: 1633621547,
+		},
+	}
+
+	//create a menu section component
+	section := &pb.MenuSection{
+		MenuSectionId: "appetizers",
+		DisplayName: &pb.TextField{
+			Text: []*localized_text.LocalizedText{{
+				Text:         "Lunch Appetizers",
+				LanguageCode: "en-us",
+			}},
+		},
+		MenuItemIds: []string{"breadsticks-sauce"},
+	}
+
+	//create a menu item component
+	item := &pb.MenuItem{
+		MenuItemId: "breadsticks-sauce",
+		DisplayName: &pb.TextField{
+			Text: []*localized_text.LocalizedText{{
+				Text:         "Breadsticks & Sauce",
+				LanguageCode: "en-us",
+			}},
+		},
+		Description: &pb.TextField{
+			Text: []*localized_text.LocalizedText{{
+				Text:         "Breakfast basket w/ side of tomato sauce (size 6 or 12)",
+				LanguageCode: "en-us",
+			}},
+		},
+		Pricing: &pb.MenuItem_MenuItemOptionSet_{
+			MenuItemOptionSet: &pb.MenuItem_MenuItemOptionSet{
+				MenuItemOptionIds: []string{"breadstick-sm", "breadstick-lg"},
+			},
+		},
+	}
+	imageUris := []string{
+		"http://www.example.com/photos/breadsticks.jpg",
+		"http://www.example.com/photos/sauce.jpg",
+	}
+	for _, uri := range imageUris {
+		image := &pb.Image{
+			Uri: uri,
+		}
+		item.Images = append(item.Images, image)
+	}
+
+	//create a menu item option
+	option := &pb.MenuItemOption{
+		MenuItemOptionId: "breadstick-sm",
+		Value: &pb.MenuItemOptionProperty{
+			PropertyType: pb.MenuItemOptionProperty_SIZE,
+			Value: &pb.MenuItemOptionProperty_TextVal{
+				TextVal: &pb.TextField{
+					Text: []*localized_text.LocalizedText{{
+						Text:         "Small",
+						LanguageCode: "en-us",
+					}},
+				},
+			},
+		},
+		OfferSet: &pb.OfferSet{
+			Offers: []*pb.Offer{{
+				Price: &money.Money{
+					CurrencyCode: "USD",
+					Units:        8,
+					Nanos:        0,
+				},
+			}},
+		},
+	}
+
+	//create feed
+	feed := &pb.FoodMenuFeed{
+		Data: []*pb.MenuComponent{{
+			Type: &pb.MenuComponent_Menu{
+				Menu: menu,
+			},
+		},
+			{
+				Type: &pb.MenuComponent_Section{
+					Section: section,
+				},
+			},
+			{
+				Type: &pb.MenuComponent_Item{
+					Item: item,
+				},
+			},
+			{
+				Type: &pb.MenuComponent_Option{
+					Option: option,
+				},
+			}},
+	}
+
+	marshalOptions := protojson.MarshalOptions{
+		UseProtoNames: true,
+	}
+	jsonBytes, _ := marshalOptions.Marshal(feed)
+	fmt.Printf("message = %s", string(jsonBytes))
+}
+
diff --git a/menu-feed/go/go.mod b/menu-feed/go/go.mod
new file mode 100644
index 0000000..732a65e
--- /dev/null
+++ b/menu-feed/go/go.mod
@@ -0,0 +1,8 @@
+module feed/app
+
+go 1.21
+
+require (
+	google.golang.org/genproto v0.0.0-20230323212658-478b75c54725
+	google.golang.org/protobuf v1.30.0
+)
diff --git a/menu-feed/go/go.sum b/menu-feed/go/go.sum
new file mode 100644
index 0000000..5a5c4ef
--- /dev/null
+++ b/menu-feed/go/go.sum
@@ -0,0 +1,10 @@
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/genproto v0.0.0-20230323212658-478b75c54725 h1:VmCWItVXcKboEMCwZaWge+1JLiTCQSngZeINF+wzO+g=
+google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
+google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
diff --git a/menu-feed/java/pom.xml b/menu-feed/java/pom.xml
new file mode 100644
index 0000000..f056542
--- /dev/null
+++ b/menu-feed/java/pom.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.example</groupId>
+    <artifactId>feed</artifactId>
+    <version>1.0.0</version>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>11.0</java.version>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+        <protobuf.version>3.22.0</protobuf.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+            <version>4.12</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+            <version>${protobuf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java-util</artifactId>
+            <version>${protobuf.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>3.2.2</version>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <addClasspath>true</addClasspath>
+                            <mainClass>com.example.Feed</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <mainClass>com.example.Feed</mainClass>
+                        </manifest>
+                    </archive>
+                    <descriptorRefs>
+                        <descriptorRef>jar-with-dependencies</descriptorRef>
+                    </descriptorRefs>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>make-assembly</id> <!-- this is used for inheritance merges -->
+                        <phase>package</phase> <!-- bind to the packaging phase -->
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/menu-feed/java/src/main/java/com/example/Feed.java b/menu-feed/java/src/main/java/com/example/Feed.java
new file mode 100644
index 0000000..a689d81
--- /dev/null
+++ b/menu-feed/java/src/main/java/com/example/Feed.java
@@ -0,0 +1,106 @@
+package com.example;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.Timestamp;
+import com.google.type.Money;
+import com.google.protobuf.util.JsonFormat;
+import com.google.type.LocalizedText;
+import food.menu.v1.FoodMenu.FoodMenuFeed;
+import food.menu.v1.FoodMenu.Menu;
+import food.menu.v1.FoodMenu.MenuComponent;
+import food.menu.v1.FoodMenu.MenuItem;
+import food.menu.v1.FoodMenu.MenuSection;
+import food.menu.v1.FoodMenu.TextField;
+import food.menu.v1.FoodMenu.MenuItemOption;
+import food.menu.v1.FoodMenu.MenuItemOptionProperty;
+import food.menu.v1.FoodMenu.OfferSet;
+import food.menu.v1.FoodMenu.Offer;
+
+/**
+ * Menu feed example used in
+ *
+ * <p>https://developers.google.com/maps-booking/verticals/dining/guides/tutorials/tutorial-menu-feed-protos#java.
+ */
+public class Feed {
+
+  public static void main(String[] args) throws InvalidProtocolBufferException {
+    Feed feed = new Feed();
+    feed.createMenuFeed();
+  }
+
+  public void createMenuFeed() throws InvalidProtocolBufferException {
+
+    Menu.Builder menu =
+        Menu.newBuilder()
+            .setMenuId("menu1")
+            .addMerchantIds("dining-1")
+            .setDisplayName(
+                TextField.newBuilder()
+                    .addText(LocalizedText.newBuilder().setText("Menu").setLanguageCode("en-us")))
+            .setLanguage("en-us")
+            .setLastMerchantUpdateTime(Timestamp.newBuilder().setSeconds(1633621547));
+
+    MenuSection.Builder section =
+        MenuSection.newBuilder()
+            .setMenuSectionId("appetizers")
+            .setDisplayName(
+                TextField.newBuilder()
+                    .addText(
+                        LocalizedText.newBuilder()
+                            .setText("Lunch Appetizers")
+                            .setLanguageCode("en-us")))
+            .addMenuItemIds("breadsticks-sauce");
+
+    MenuItem.Builder item =
+        MenuItem.newBuilder()
+            .setMenuItemId("breadsticks-sauce")
+            .setDisplayName(
+                TextField.newBuilder()
+                    .addText(
+                        LocalizedText.newBuilder()
+                            .setText("Breadsticks & Sauce")
+                            .setLanguageCode("en-us")))
+            .setDescription(
+                TextField.newBuilder()
+                    .addText(
+                        LocalizedText.newBuilder()
+                            .setText("Breadsticks & Sauce")
+                            .setLanguageCode("en-us")));
+
+    MenuItemOption.Builder option =
+        MenuItemOption.newBuilder()
+          .setMenuItemOptionId("breadstick-sm")
+          .setValue(
+              MenuItemOptionProperty.newBuilder()
+                .setPropertyType(MenuItemOptionProperty.PropertyType.SIZE)
+                .setTextVal(TextField.newBuilder()
+                    .addText(
+                        LocalizedText.newBuilder()
+                            .setText("Small")
+                            .setLanguageCode("en-us"))))
+          .setOfferSet(
+              OfferSet.newBuilder()
+                .addOffers(
+                    Offer.newBuilder()
+                      .setPrice(
+                          Money.newBuilder()
+                            .setCurrencyCode("USD")
+                            .setUnits(8)
+                            .setNanos(0))));
+
+    FoodMenuFeed.Builder foodMenuFeed =
+        FoodMenuFeed.newBuilder()
+            .addData(MenuComponent.newBuilder().setMenu(menu))
+            .addData(MenuComponent.newBuilder().setSection(section))
+            .addData(MenuComponent.newBuilder().setItem(item))
+            .addData(MenuComponent.newBuilder().setOption(option));
+
+    String feedJSON =
+        JsonFormat.printer()
+            .omittingInsignificantWhitespace()
+            .preservingProtoFieldNames()
+            .print(foodMenuFeed);
+
+    System.out.println(feedJSON);
+  }
+}
diff --git a/menu-feed/java/src/main/java/com/google/type/LocalizedText.java b/menu-feed/java/src/main/java/com/google/type/LocalizedText.java
new file mode 100644
index 0000000..716ed77
--- /dev/null
+++ b/menu-feed/java/src/main/java/com/google/type/LocalizedText.java
@@ -0,0 +1,728 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: localized_text.proto
+
+package com.google.type;
+
+/**
+ * <pre>
+ * Localized variant of a text in a particular language.
+ * </pre>
+ *
+ * Protobuf type {@code google.type.LocalizedText}
+ */
+public final class LocalizedText extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:google.type.LocalizedText)
+    LocalizedTextOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use LocalizedText.newBuilder() to construct.
+  private LocalizedText(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private LocalizedText() {
+    text_ = "";
+    languageCode_ = "";
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new LocalizedText();
+  }
+
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return com.google.type.LocalizedTextProto.internal_static_google_type_LocalizedText_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return com.google.type.LocalizedTextProto.internal_static_google_type_LocalizedText_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            com.google.type.LocalizedText.class, com.google.type.LocalizedText.Builder.class);
+  }
+
+  public static final int TEXT_FIELD_NUMBER = 1;
+  @SuppressWarnings("serial")
+  private volatile java.lang.Object text_ = "";
+  /**
+   * <pre>
+   * Localized string in the language corresponding to `language_code' below.
+   * </pre>
+   *
+   * <code>string text = 1;</code>
+   * @return The text.
+   */
+  @java.lang.Override
+  public java.lang.String getText() {
+    java.lang.Object ref = text_;
+    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();
+      text_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * Localized string in the language corresponding to `language_code' below.
+   * </pre>
+   *
+   * <code>string text = 1;</code>
+   * @return The bytes for text.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getTextBytes() {
+    java.lang.Object ref = text_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      text_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int LANGUAGE_CODE_FIELD_NUMBER = 2;
+  @SuppressWarnings("serial")
+  private volatile java.lang.Object languageCode_ = "";
+  /**
+   * <pre>
+   * The text's BCP-47 language code, such as "en-US" or "sr-Latn".
+   *
+   * For more information, see
+   * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+   * </pre>
+   *
+   * <code>string language_code = 2;</code>
+   * @return The languageCode.
+   */
+  @java.lang.Override
+  public java.lang.String getLanguageCode() {
+    java.lang.Object ref = languageCode_;
+    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();
+      languageCode_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * The text's BCP-47 language code, such as "en-US" or "sr-Latn".
+   *
+   * For more information, see
+   * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+   * </pre>
+   *
+   * <code>string language_code = 2;</code>
+   * @return The bytes for languageCode.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getLanguageCodeBytes() {
+    java.lang.Object ref = languageCode_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      languageCode_ = 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(text_)) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 1, text_);
+    }
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(languageCode_)) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, languageCode_);
+    }
+    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(text_)) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, text_);
+    }
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(languageCode_)) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, languageCode_);
+    }
+    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 com.google.type.LocalizedText)) {
+      return super.equals(obj);
+    }
+    com.google.type.LocalizedText other = (com.google.type.LocalizedText) obj;
+
+    if (!getText()
+        .equals(other.getText())) return false;
+    if (!getLanguageCode()
+        .equals(other.getLanguageCode())) 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) + TEXT_FIELD_NUMBER;
+    hash = (53 * hash) + getText().hashCode();
+    hash = (37 * hash) + LANGUAGE_CODE_FIELD_NUMBER;
+    hash = (53 * hash) + getLanguageCode().hashCode();
+    hash = (29 * hash) + getUnknownFields().hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static com.google.type.LocalizedText parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.google.type.LocalizedText parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.google.type.LocalizedText parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.google.type.LocalizedText parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.google.type.LocalizedText parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.google.type.LocalizedText parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.google.type.LocalizedText parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.google.type.LocalizedText 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 com.google.type.LocalizedText parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static com.google.type.LocalizedText 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 com.google.type.LocalizedText parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.google.type.LocalizedText 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(com.google.type.LocalizedText 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>
+   * Localized variant of a text in a particular language.
+   * </pre>
+   *
+   * Protobuf type {@code google.type.LocalizedText}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:google.type.LocalizedText)
+      com.google.type.LocalizedTextOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.google.type.LocalizedTextProto.internal_static_google_type_LocalizedText_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.google.type.LocalizedTextProto.internal_static_google_type_LocalizedText_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.google.type.LocalizedText.class, com.google.type.LocalizedText.Builder.class);
+    }
+
+    // Construct using com.google.type.LocalizedText.newBuilder()
+    private Builder() {
+
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      bitField0_ = 0;
+      text_ = "";
+      languageCode_ = "";
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return com.google.type.LocalizedTextProto.internal_static_google_type_LocalizedText_descriptor;
+    }
+
+    @java.lang.Override
+    public com.google.type.LocalizedText getDefaultInstanceForType() {
+      return com.google.type.LocalizedText.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public com.google.type.LocalizedText build() {
+      com.google.type.LocalizedText result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public com.google.type.LocalizedText buildPartial() {
+      com.google.type.LocalizedText result = new com.google.type.LocalizedText(this);
+      if (bitField0_ != 0) { buildPartial0(result); }
+      onBuilt();
+      return result;
+    }
+
+    private void buildPartial0(com.google.type.LocalizedText result) {
+      int from_bitField0_ = bitField0_;
+      if (((from_bitField0_ & 0x00000001) != 0)) {
+        result.text_ = text_;
+      }
+      if (((from_bitField0_ & 0x00000002) != 0)) {
+        result.languageCode_ = languageCode_;
+      }
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof com.google.type.LocalizedText) {
+        return mergeFrom((com.google.type.LocalizedText)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(com.google.type.LocalizedText other) {
+      if (other == com.google.type.LocalizedText.getDefaultInstance()) return this;
+      if (!other.getText().isEmpty()) {
+        text_ = other.text_;
+        bitField0_ |= 0x00000001;
+        onChanged();
+      }
+      if (!other.getLanguageCode().isEmpty()) {
+        languageCode_ = other.languageCode_;
+        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: {
+              text_ = input.readStringRequireUtf8();
+              bitField0_ |= 0x00000001;
+              break;
+            } // case 10
+            case 18: {
+              languageCode_ = 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 java.lang.Object text_ = "";
+    /**
+     * <pre>
+     * Localized string in the language corresponding to `language_code' below.
+     * </pre>
+     *
+     * <code>string text = 1;</code>
+     * @return The text.
+     */
+    public java.lang.String getText() {
+      java.lang.Object ref = text_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        text_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * Localized string in the language corresponding to `language_code' below.
+     * </pre>
+     *
+     * <code>string text = 1;</code>
+     * @return The bytes for text.
+     */
+    public com.google.protobuf.ByteString
+        getTextBytes() {
+      java.lang.Object ref = text_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        text_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * Localized string in the language corresponding to `language_code' below.
+     * </pre>
+     *
+     * <code>string text = 1;</code>
+     * @param value The text to set.
+     * @return This builder for chaining.
+     */
+    public Builder setText(
+        java.lang.String value) {
+      if (value == null) { throw new NullPointerException(); }
+      text_ = value;
+      bitField0_ |= 0x00000001;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * Localized string in the language corresponding to `language_code' below.
+     * </pre>
+     *
+     * <code>string text = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearText() {
+      text_ = getDefaultInstance().getText();
+      bitField0_ = (bitField0_ & ~0x00000001);
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * Localized string in the language corresponding to `language_code' below.
+     * </pre>
+     *
+     * <code>string text = 1;</code>
+     * @param value The bytes for text to set.
+     * @return This builder for chaining.
+     */
+    public Builder setTextBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) { throw new NullPointerException(); }
+      checkByteStringIsUtf8(value);
+      text_ = value;
+      bitField0_ |= 0x00000001;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object languageCode_ = "";
+    /**
+     * <pre>
+     * The text's BCP-47 language code, such as "en-US" or "sr-Latn".
+     *
+     * For more information, see
+     * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+     * </pre>
+     *
+     * <code>string language_code = 2;</code>
+     * @return The languageCode.
+     */
+    public java.lang.String getLanguageCode() {
+      java.lang.Object ref = languageCode_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        languageCode_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * The text's BCP-47 language code, such as "en-US" or "sr-Latn".
+     *
+     * For more information, see
+     * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+     * </pre>
+     *
+     * <code>string language_code = 2;</code>
+     * @return The bytes for languageCode.
+     */
+    public com.google.protobuf.ByteString
+        getLanguageCodeBytes() {
+      java.lang.Object ref = languageCode_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        languageCode_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * The text's BCP-47 language code, such as "en-US" or "sr-Latn".
+     *
+     * For more information, see
+     * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+     * </pre>
+     *
+     * <code>string language_code = 2;</code>
+     * @param value The languageCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setLanguageCode(
+        java.lang.String value) {
+      if (value == null) { throw new NullPointerException(); }
+      languageCode_ = value;
+      bitField0_ |= 0x00000002;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The text's BCP-47 language code, such as "en-US" or "sr-Latn".
+     *
+     * For more information, see
+     * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+     * </pre>
+     *
+     * <code>string language_code = 2;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearLanguageCode() {
+      languageCode_ = getDefaultInstance().getLanguageCode();
+      bitField0_ = (bitField0_ & ~0x00000002);
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The text's BCP-47 language code, such as "en-US" or "sr-Latn".
+     *
+     * For more information, see
+     * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+     * </pre>
+     *
+     * <code>string language_code = 2;</code>
+     * @param value The bytes for languageCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setLanguageCodeBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) { throw new NullPointerException(); }
+      checkByteStringIsUtf8(value);
+      languageCode_ = 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:google.type.LocalizedText)
+  }
+
+  // @@protoc_insertion_point(class_scope:google.type.LocalizedText)
+  private static final com.google.type.LocalizedText DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new com.google.type.LocalizedText();
+  }
+
+  public static com.google.type.LocalizedText getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<LocalizedText>
+      PARSER = new com.google.protobuf.AbstractParser<LocalizedText>() {
+    @java.lang.Override
+    public LocalizedText 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<LocalizedText> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<LocalizedText> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.type.LocalizedText getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/menu-feed/java/src/main/java/com/google/type/LocalizedTextOrBuilder.java b/menu-feed/java/src/main/java/com/google/type/LocalizedTextOrBuilder.java
new file mode 100644
index 0000000..4d4a2c0
--- /dev/null
+++ b/menu-feed/java/src/main/java/com/google/type/LocalizedTextOrBuilder.java
@@ -0,0 +1,55 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: localized_text.proto
+
+package com.google.type;
+
+public interface LocalizedTextOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:google.type.LocalizedText)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <pre>
+   * Localized string in the language corresponding to `language_code' below.
+   * </pre>
+   *
+   * <code>string text = 1;</code>
+   * @return The text.
+   */
+  java.lang.String getText();
+  /**
+   * <pre>
+   * Localized string in the language corresponding to `language_code' below.
+   * </pre>
+   *
+   * <code>string text = 1;</code>
+   * @return The bytes for text.
+   */
+  com.google.protobuf.ByteString
+      getTextBytes();
+
+  /**
+   * <pre>
+   * The text's BCP-47 language code, such as "en-US" or "sr-Latn".
+   *
+   * For more information, see
+   * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+   * </pre>
+   *
+   * <code>string language_code = 2;</code>
+   * @return The languageCode.
+   */
+  java.lang.String getLanguageCode();
+  /**
+   * <pre>
+   * The text's BCP-47 language code, such as "en-US" or "sr-Latn".
+   *
+   * For more information, see
+   * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+   * </pre>
+   *
+   * <code>string language_code = 2;</code>
+   * @return The bytes for languageCode.
+   */
+  com.google.protobuf.ByteString
+      getLanguageCodeBytes();
+}
diff --git a/menu-feed/java/src/main/java/com/google/type/LocalizedTextProto.java b/menu-feed/java/src/main/java/com/google/type/LocalizedTextProto.java
new file mode 100644
index 0000000..6d8137f
--- /dev/null
+++ b/menu-feed/java/src/main/java/com/google/type/LocalizedTextProto.java
@@ -0,0 +1,51 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: localized_text.proto
+
+package com.google.type;
+
+public final class LocalizedTextProto {
+  private LocalizedTextProto() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_google_type_LocalizedText_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_google_type_LocalizedText_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\024localized_text.proto\022\013google.type\"4\n\rL" +
+      "ocalizedText\022\014\n\004text\030\001 \001(\t\022\025\n\rlanguage_c" +
+      "ode\030\002 \001(\tBz\n\017com.google.typeB\022LocalizedT" +
+      "extProtoP\001ZHgoogle.golang.org/genproto/g" +
+      "oogleapis/type/localized_text;localized_" +
+      "text\370\001\001\242\002\003GTPb\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        });
+    internal_static_google_type_LocalizedText_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_google_type_LocalizedText_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_google_type_LocalizedText_descriptor,
+        new java.lang.String[] { "Text", "LanguageCode", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/menu-feed/java/src/main/java/com/google/type/Money.java b/menu-feed/java/src/main/java/com/google/type/Money.java
new file mode 100644
index 0000000..c921feb
--- /dev/null
+++ b/menu-feed/java/src/main/java/com/google/type/Money.java
@@ -0,0 +1,732 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: money.proto
+
+package com.google.type;
+
+/**
+ * <pre>
+ * Represents an amount of money with its currency type.
+ * </pre>
+ *
+ * Protobuf type {@code google.type.Money}
+ */
+public final class Money extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:google.type.Money)
+    MoneyOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use Money.newBuilder() to construct.
+  private Money(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private Money() {
+    currencyCode_ = "";
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new Money();
+  }
+
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return com.google.type.MoneyProto.internal_static_google_type_Money_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return com.google.type.MoneyProto.internal_static_google_type_Money_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            com.google.type.Money.class, com.google.type.Money.Builder.class);
+  }
+
+  public static final int CURRENCY_CODE_FIELD_NUMBER = 1;
+  @SuppressWarnings("serial")
+  private volatile java.lang.Object currencyCode_ = "";
+  /**
+   * <pre>
+   * The three-letter currency code defined in ISO 4217.
+   * </pre>
+   *
+   * <code>string currency_code = 1;</code>
+   * @return The currencyCode.
+   */
+  @java.lang.Override
+  public java.lang.String getCurrencyCode() {
+    java.lang.Object ref = currencyCode_;
+    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();
+      currencyCode_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * The three-letter currency code defined in ISO 4217.
+   * </pre>
+   *
+   * <code>string currency_code = 1;</code>
+   * @return The bytes for currencyCode.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getCurrencyCodeBytes() {
+    java.lang.Object ref = currencyCode_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      currencyCode_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int UNITS_FIELD_NUMBER = 2;
+  private long units_ = 0L;
+  /**
+   * <pre>
+   * The whole units of the amount.
+   * For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar.
+   * </pre>
+   *
+   * <code>int64 units = 2;</code>
+   * @return The units.
+   */
+  @java.lang.Override
+  public long getUnits() {
+    return units_;
+  }
+
+  public static final int NANOS_FIELD_NUMBER = 3;
+  private int nanos_ = 0;
+  /**
+   * <pre>
+   * Number of nano (10^-9) units of the amount.
+   * The value must be between -999,999,999 and +999,999,999 inclusive.
+   * If `units` is positive, `nanos` must be positive or zero.
+   * If `units` is zero, `nanos` can be positive, zero, or negative.
+   * If `units` is negative, `nanos` must be negative or zero.
+   * For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
+   * </pre>
+   *
+   * <code>int32 nanos = 3;</code>
+   * @return The nanos.
+   */
+  @java.lang.Override
+  public int getNanos() {
+    return nanos_;
+  }
+
+  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(currencyCode_)) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 1, currencyCode_);
+    }
+    if (units_ != 0L) {
+      output.writeInt64(2, units_);
+    }
+    if (nanos_ != 0) {
+      output.writeInt32(3, nanos_);
+    }
+    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(currencyCode_)) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, currencyCode_);
+    }
+    if (units_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(2, units_);
+    }
+    if (nanos_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt32Size(3, nanos_);
+    }
+    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 com.google.type.Money)) {
+      return super.equals(obj);
+    }
+    com.google.type.Money other = (com.google.type.Money) obj;
+
+    if (!getCurrencyCode()
+        .equals(other.getCurrencyCode())) return false;
+    if (getUnits()
+        != other.getUnits()) return false;
+    if (getNanos()
+        != other.getNanos()) 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) + CURRENCY_CODE_FIELD_NUMBER;
+    hash = (53 * hash) + getCurrencyCode().hashCode();
+    hash = (37 * hash) + UNITS_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getUnits());
+    hash = (37 * hash) + NANOS_FIELD_NUMBER;
+    hash = (53 * hash) + getNanos();
+    hash = (29 * hash) + getUnknownFields().hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static com.google.type.Money parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.google.type.Money parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.google.type.Money parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.google.type.Money parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.google.type.Money parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.google.type.Money parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.google.type.Money parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.google.type.Money 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 com.google.type.Money parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static com.google.type.Money 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 com.google.type.Money parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.google.type.Money 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(com.google.type.Money 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 amount of money with its currency type.
+   * </pre>
+   *
+   * Protobuf type {@code google.type.Money}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:google.type.Money)
+      com.google.type.MoneyOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.google.type.MoneyProto.internal_static_google_type_Money_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.google.type.MoneyProto.internal_static_google_type_Money_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.google.type.Money.class, com.google.type.Money.Builder.class);
+    }
+
+    // Construct using com.google.type.Money.newBuilder()
+    private Builder() {
+
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      bitField0_ = 0;
+      currencyCode_ = "";
+      units_ = 0L;
+      nanos_ = 0;
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return com.google.type.MoneyProto.internal_static_google_type_Money_descriptor;
+    }
+
+    @java.lang.Override
+    public com.google.type.Money getDefaultInstanceForType() {
+      return com.google.type.Money.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public com.google.type.Money build() {
+      com.google.type.Money result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public com.google.type.Money buildPartial() {
+      com.google.type.Money result = new com.google.type.Money(this);
+      if (bitField0_ != 0) { buildPartial0(result); }
+      onBuilt();
+      return result;
+    }
+
+    private void buildPartial0(com.google.type.Money result) {
+      int from_bitField0_ = bitField0_;
+      if (((from_bitField0_ & 0x00000001) != 0)) {
+        result.currencyCode_ = currencyCode_;
+      }
+      if (((from_bitField0_ & 0x00000002) != 0)) {
+        result.units_ = units_;
+      }
+      if (((from_bitField0_ & 0x00000004) != 0)) {
+        result.nanos_ = nanos_;
+      }
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof com.google.type.Money) {
+        return mergeFrom((com.google.type.Money)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(com.google.type.Money other) {
+      if (other == com.google.type.Money.getDefaultInstance()) return this;
+      if (!other.getCurrencyCode().isEmpty()) {
+        currencyCode_ = other.currencyCode_;
+        bitField0_ |= 0x00000001;
+        onChanged();
+      }
+      if (other.getUnits() != 0L) {
+        setUnits(other.getUnits());
+      }
+      if (other.getNanos() != 0) {
+        setNanos(other.getNanos());
+      }
+      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: {
+              currencyCode_ = input.readStringRequireUtf8();
+              bitField0_ |= 0x00000001;
+              break;
+            } // case 10
+            case 16: {
+              units_ = input.readInt64();
+              bitField0_ |= 0x00000002;
+              break;
+            } // case 16
+            case 24: {
+              nanos_ = input.readInt32();
+              bitField0_ |= 0x00000004;
+              break;
+            } // case 24
+            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 currencyCode_ = "";
+    /**
+     * <pre>
+     * The three-letter currency code defined in ISO 4217.
+     * </pre>
+     *
+     * <code>string currency_code = 1;</code>
+     * @return The currencyCode.
+     */
+    public java.lang.String getCurrencyCode() {
+      java.lang.Object ref = currencyCode_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        currencyCode_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * The three-letter currency code defined in ISO 4217.
+     * </pre>
+     *
+     * <code>string currency_code = 1;</code>
+     * @return The bytes for currencyCode.
+     */
+    public com.google.protobuf.ByteString
+        getCurrencyCodeBytes() {
+      java.lang.Object ref = currencyCode_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        currencyCode_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * The three-letter currency code defined in ISO 4217.
+     * </pre>
+     *
+     * <code>string currency_code = 1;</code>
+     * @param value The currencyCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCurrencyCode(
+        java.lang.String value) {
+      if (value == null) { throw new NullPointerException(); }
+      currencyCode_ = value;
+      bitField0_ |= 0x00000001;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The three-letter currency code defined in ISO 4217.
+     * </pre>
+     *
+     * <code>string currency_code = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearCurrencyCode() {
+      currencyCode_ = getDefaultInstance().getCurrencyCode();
+      bitField0_ = (bitField0_ & ~0x00000001);
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The three-letter currency code defined in ISO 4217.
+     * </pre>
+     *
+     * <code>string currency_code = 1;</code>
+     * @param value The bytes for currencyCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCurrencyCodeBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) { throw new NullPointerException(); }
+      checkByteStringIsUtf8(value);
+      currencyCode_ = value;
+      bitField0_ |= 0x00000001;
+      onChanged();
+      return this;
+    }
+
+    private long units_ ;
+    /**
+     * <pre>
+     * The whole units of the amount.
+     * For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar.
+     * </pre>
+     *
+     * <code>int64 units = 2;</code>
+     * @return The units.
+     */
+    @java.lang.Override
+    public long getUnits() {
+      return units_;
+    }
+    /**
+     * <pre>
+     * The whole units of the amount.
+     * For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar.
+     * </pre>
+     *
+     * <code>int64 units = 2;</code>
+     * @param value The units to set.
+     * @return This builder for chaining.
+     */
+    public Builder setUnits(long value) {
+
+      units_ = value;
+      bitField0_ |= 0x00000002;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The whole units of the amount.
+     * For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar.
+     * </pre>
+     *
+     * <code>int64 units = 2;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearUnits() {
+      bitField0_ = (bitField0_ & ~0x00000002);
+      units_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private int nanos_ ;
+    /**
+     * <pre>
+     * Number of nano (10^-9) units of the amount.
+     * The value must be between -999,999,999 and +999,999,999 inclusive.
+     * If `units` is positive, `nanos` must be positive or zero.
+     * If `units` is zero, `nanos` can be positive, zero, or negative.
+     * If `units` is negative, `nanos` must be negative or zero.
+     * For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
+     * </pre>
+     *
+     * <code>int32 nanos = 3;</code>
+     * @return The nanos.
+     */
+    @java.lang.Override
+    public int getNanos() {
+      return nanos_;
+    }
+    /**
+     * <pre>
+     * Number of nano (10^-9) units of the amount.
+     * The value must be between -999,999,999 and +999,999,999 inclusive.
+     * If `units` is positive, `nanos` must be positive or zero.
+     * If `units` is zero, `nanos` can be positive, zero, or negative.
+     * If `units` is negative, `nanos` must be negative or zero.
+     * For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
+     * </pre>
+     *
+     * <code>int32 nanos = 3;</code>
+     * @param value The nanos to set.
+     * @return This builder for chaining.
+     */
+    public Builder setNanos(int value) {
+
+      nanos_ = value;
+      bitField0_ |= 0x00000004;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * Number of nano (10^-9) units of the amount.
+     * The value must be between -999,999,999 and +999,999,999 inclusive.
+     * If `units` is positive, `nanos` must be positive or zero.
+     * If `units` is zero, `nanos` can be positive, zero, or negative.
+     * If `units` is negative, `nanos` must be negative or zero.
+     * For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
+     * </pre>
+     *
+     * <code>int32 nanos = 3;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearNanos() {
+      bitField0_ = (bitField0_ & ~0x00000004);
+      nanos_ = 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:google.type.Money)
+  }
+
+  // @@protoc_insertion_point(class_scope:google.type.Money)
+  private static final com.google.type.Money DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new com.google.type.Money();
+  }
+
+  public static com.google.type.Money getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<Money>
+      PARSER = new com.google.protobuf.AbstractParser<Money>() {
+    @java.lang.Override
+    public Money 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<Money> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<Money> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.type.Money getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/menu-feed/java/src/main/java/com/google/type/MoneyOrBuilder.java b/menu-feed/java/src/main/java/com/google/type/MoneyOrBuilder.java
new file mode 100644
index 0000000..ed05c1e
--- /dev/null
+++ b/menu-feed/java/src/main/java/com/google/type/MoneyOrBuilder.java
@@ -0,0 +1,55 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: money.proto
+
+package com.google.type;
+
+public interface MoneyOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:google.type.Money)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <pre>
+   * The three-letter currency code defined in ISO 4217.
+   * </pre>
+   *
+   * <code>string currency_code = 1;</code>
+   * @return The currencyCode.
+   */
+  java.lang.String getCurrencyCode();
+  /**
+   * <pre>
+   * The three-letter currency code defined in ISO 4217.
+   * </pre>
+   *
+   * <code>string currency_code = 1;</code>
+   * @return The bytes for currencyCode.
+   */
+  com.google.protobuf.ByteString
+      getCurrencyCodeBytes();
+
+  /**
+   * <pre>
+   * The whole units of the amount.
+   * For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar.
+   * </pre>
+   *
+   * <code>int64 units = 2;</code>
+   * @return The units.
+   */
+  long getUnits();
+
+  /**
+   * <pre>
+   * Number of nano (10^-9) units of the amount.
+   * The value must be between -999,999,999 and +999,999,999 inclusive.
+   * If `units` is positive, `nanos` must be positive or zero.
+   * If `units` is zero, `nanos` can be positive, zero, or negative.
+   * If `units` is negative, `nanos` must be negative or zero.
+   * For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
+   * </pre>
+   *
+   * <code>int32 nanos = 3;</code>
+   * @return The nanos.
+   */
+  int getNanos();
+}
diff --git a/menu-feed/java/src/main/java/com/google/type/MoneyProto.java b/menu-feed/java/src/main/java/com/google/type/MoneyProto.java
new file mode 100644
index 0000000..24fe444
--- /dev/null
+++ b/menu-feed/java/src/main/java/com/google/type/MoneyProto.java
@@ -0,0 +1,50 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: money.proto
+
+package com.google.type;
+
+public final class MoneyProto {
+  private MoneyProto() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_google_type_Money_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_google_type_Money_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\013money.proto\022\013google.type\"<\n\005Money\022\025\n\rc" +
+      "urrency_code\030\001 \001(\t\022\r\n\005units\030\002 \001(\003\022\r\n\005nan" +
+      "os\030\003 \001(\005B`\n\017com.google.typeB\nMoneyProtoP" +
+      "\001Z6google.golang.org/genproto/googleapis" +
+      "/type/money;money\370\001\001\242\002\003GTPb\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        });
+    internal_static_google_type_Money_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_google_type_Money_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_google_type_Money_descriptor,
+        new java.lang.String[] { "CurrencyCode", "Units", "Nanos", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/menu-feed/java/src/main/java/food/menu/v1/FoodMenu.java b/menu-feed/java/src/main/java/food/menu/v1/FoodMenu.java
new file mode 100644
index 0000000..4a0936d
--- /dev/null
+++ b/menu-feed/java/src/main/java/food/menu/v1/FoodMenu.java
@@ -0,0 +1,26852 @@
+// 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)
+}
diff --git a/menu-feed/proto/food_menu.proto b/menu-feed/proto/food_menu.proto
new file mode 100644
index 0000000..62689d8
--- /dev/null
+++ b/menu-feed/proto/food_menu.proto
@@ -0,0 +1,531 @@
+
+  // Feeds declaration
+  syntax = "proto3";
+  
+  package food.menu.v1;
+
+  import "google/protobuf/timestamp.proto";
+  import "money.proto";
+  import "localized_text.proto";
+
+  option go_package = "food/menu/v1/proto";
+
+  
+  message FoodMenuFeed {
+  repeated MenuComponent data = 1;
+}
+  
+  message MenuComponent {
+  oneof type {
+    food.menu.v1.Menu menu = 1;
+    food.menu.v1.MenuSection section = 2;
+    food.menu.v1.MenuItem item = 3;
+    food.menu.v1.MenuItemOption option = 4;
+  }
+}
+  
+  // 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.
+message Menu {
+  // An opaque string from a partner which uniquely identifies the Menu within
+  // the partner feed.
+  // Required.
+  string menu_id = 1;
+
+  // 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.
+  repeated string merchant_ids = 2;
+
+  // The name that can identify the Menu when a user is browsing the menu.
+  // Optional.
+  TextField display_name = 3;
+
+  // 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.
+  string language = 4;
+
+  // Disclaimer to be shown to the user for the menu. For example, nutritional
+  // information disclosure and allergen disclosure.
+  // Optional.
+  Disclaimer disclaimer = 5;
+
+  // IDs of items contained within this menu. Expects first-level menu items
+  // only.
+  // Optional.
+  repeated string menu_item_ids = 6;
+
+  // IDs of sections contained within this menu. Expects first-level menu
+  // sections only.
+  // Optional.
+  repeated string menu_section_ids = 7;
+
+  // 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.
+  google.protobuf.Timestamp last_merchant_update_time = 8;
+
+}
+  
+  // 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.
+message MenuSection {
+  // An opaque string from an partner which uniquely identifies the MenuSection
+  // within the partner feed.
+  // Required.
+  string menu_section_id = 1;
+
+  // The name that can identify the MenuSection when a user is browsing the
+  // menu.
+  // Required.
+  TextField display_name = 2;
+
+  // A description of the menu section.
+  // Optional.
+  TextField description = 3;
+
+  // Image(s) of the menu section.
+  // Optional.
+  repeated Image images = 4;
+
+
+  // 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.
+  repeated string menu_item_ids = 6;
+
+  // Child MenuSections (sub-sections) that correspond to this MenuSection
+  // entity.
+  // Optional.
+  repeated string menu_section_ids = 7;
+
+
+
+
+
+
+}
+  
+  // Represents a single food or drink item offered by a Food establishment.
+message MenuItem {
+  // An opaque string from an partner which uniquely identifies the MenuItem
+  // within the partner feed.
+  // Required.
+  string menu_item_id = 1;
+
+  // The name that can identify the MenuItem when a user is browsing the menu.
+  // Required.
+  TextField display_name = 2;
+
+  // A description of the menu item.
+  // Optional.
+  TextField description = 3;
+
+  // Image(s) of the menu item.
+  // Optional.
+  repeated Image images = 4;
+
+  // Container that specifies a list of options available on an item.
+  message MenuItemOptionSet {
+    // IDs of menu item options that are applicable to this menu item.
+    // Required.
+    repeated string menu_item_option_ids = 1;
+  }
+
+  // The menu item must either have a price, or a set of menu item options.
+  // Required.
+  oneof pricing {
+    // Available offers to purchase this food item.
+    OfferSet offer_set = 6;
+
+    // Available options for this menu item.
+    MenuItemOptionSet menu_item_option_set = 7;
+  }
+
+  // Attributes about this menu item.
+  // Optional.
+  MenuItemAttributes item_attributes = 8;
+
+
+}
+  
+  // 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).
+message MenuItemOption {
+  // An opaque string from an partner which uniquely identifies the
+  // MenuItemOption within the partner feed.
+  // Required.
+  string menu_item_option_id = 9;
+
+  // Option property and value e.g. Size: Small.
+  // Required.
+  MenuItemOptionProperty value = 2;
+
+
+
+  // Available offers to purchase this menu item option.
+  // Required.
+  OfferSet offer_set = 4;
+
+  // Attributes about this menu item option.
+  // Optional.
+  MenuItemAttributes item_attributes = 5;
+
+
+}
+  
+  // Describes attributes about a particular menu item or option.
+message MenuItemAttributes {
+  // Number of servings available in a given menu item.
+  // Optional.
+  optional int32 number_of_servings = 1;
+
+  // Describes all the nutritional information of the item, e.g. calories, fat
+  // content.
+  // Optional.
+  NutritionInformation nutrition_information = 2;
+
+  // The dietary restrictions that this menu item complies with.
+  // Optional.
+  repeated DietaryRestriction suitable_diets = 3;
+
+  // Additives of this menu item.
+  // Optional.
+  repeated Additive additive = 4;
+
+  // Allergens of this menu item.
+  // Optional.
+  repeated Allergen allergen = 5;
+
+  // Packaging and recycling information of this menu item.
+  // Optional.
+  DepositInfo packaging_deposit_info = 6;
+}
+  
+  // 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.
+message OfferSet {
+  // List of possible offers.
+  // Required.
+  repeated Offer offers = 1;
+}
+
+  // Represents pricing and availability information for MenuItems and
+// MenuItemOptions.
+message Offer {
+  // Monetary value of the menu item/option on sale. Can be 0 to represent free.
+  // Required.
+  google.type.Money price = 1;
+
+
+
+
+
+
+}
+  
+  // 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.
+message Disclaimer {
+  // Body of the disclaimer text to be shown to the user.
+  // Required.
+  TextField text = 1;
+
+  // URL containing more information about the disclaimer.
+  // Optional.
+  string uri = 2;
+}
+  
+  // A text payload that contains one or more localized values.
+message TextField {
+  // 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.
+  repeated google.type.LocalizedText text = 1;
+}
+  
+  // Represents an image associated with a menu entity.
+message Image {
+  // URL containing the raw pixels of the image.
+  // Required.
+  string uri = 1;
+}
+
+  // Describes the property of a menu item option and its value.
+message MenuItemOptionProperty {
+  // Types of property that the option is for.
+  enum PropertyType {
+    // Do not use. The property type is not explicitly specified.
+    UNKNOWN_PROPERTY_TYPE = 0;
+    // 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.
+    OPTION = 1;
+    // Denotes the menu item option property of size (e.g. small, medium, or
+    // large).
+    SIZE = 2;
+    // 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).
+    PIZZA_SIDE = 3;
+  }
+
+  // Well-defined values for the option property.
+  enum PropertyValue {
+    // Do not use. The property value is not explicitly specified.
+    UNKNOWN_PROPERTY_VALUE = 0;
+    // The MenuItemOption applies only to the left side of a pizza.
+    PIZZA_SIDE_LEFT = 1;
+    // The MenuItemOption applies only to the right side of a pizza.
+    PIZZA_SIDE_RIGHT = 2;
+    // The MenuItemOption applies to the entire pizza.
+    PIZZA_SIDE_WHOLE = 3;
+  }
+
+  // The type of this option property.
+  // Required.
+  PropertyType property_type = 1;
+
+  // Required.
+  oneof value {
+    // A well-defined value for the option property. Currently only expected
+    // if the property_type is PIZZA_SIDE.
+    PropertyValue property_val = 2;
+
+    // A free-form text for the value of the property. Expected for
+    // property_type OPTION and SIZE.
+    TextField text_val = 3;
+  }
+}
+  
+  // Describes all the nutritional measurements of a MenuItem or add-on.
+message NutritionInformation {
+  // Describes a single nutritional measurement of the serving of food.
+  message NutritionValue {
+    // Describes a closed range for the nutrition value. E.g. "100-150 cal"
+    message Range {
+      // The minimum amount of nutrition value.
+      // Required.
+      double min = 1;
+
+      // The maximum amount of nutrition value.
+      // Required.
+      double max = 2;
+    }
+
+    // Required oneof.
+    oneof value {
+      // A single number representing the amount of nutritional value.
+      double amount = 1;
+
+      // A range representing the amount of nutritional value.
+      Range range = 3;
+    }
+
+    // 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.
+    NutritionValueUnit unit = 2;
+  }
+
+  // The amount of nutritional energy of the serving of food. Can be defined
+  // in Calories or kilojoules.
+  // Optional.
+  NutritionValue energy = 1;
+
+  // The amount of sodium content, measured in grams or milligrams.
+  // Optional.
+  NutritionValue sodium_content = 2;
+
+  // The number of servings the nutrition value applies to.
+  // Optional.
+  optional int32 serving_size = 3;
+
+  // Nutrition information in free text. For example "Contains preservatives".
+  // Optional.
+  TextField description = 4;
+}
+  
+  // Indicates a dietary restriction or guideline adhered to during
+// food preparation.
+enum DietaryRestriction {
+  // Do not use. The dietary restriction is not explicitly specified.
+  DIET_UNSPECIFIED = 0;
+  DIET_DIABETIC = 1;
+  DIET_GLUTEN_FREE = 2;
+  DIET_HALAL = 3;
+  DIET_HINDU = 4;
+  DIET_KOSHER = 5;
+  DIET_LOW_CALORIE = 6;
+  DIET_LOW_FAT = 7;
+  DIET_LOW_LACTOSE = 8;
+  DIET_LOW_SALT = 9;
+  DIET_VEGAN = 10;
+  DIET_VEGETARIAN = 11;
+}
+
+  // Additive shown to the user on the MenuItem. An additive preserves or enhances
+// the quality of the food.
+message Additive {
+  // Descriptive text of the additive, e.g. "preservatives".
+  // Required.
+  TextField name = 1;
+
+  // Whether the MenuItem contains, may contain, or is free from this additive.
+  // Defaults to contains.
+  // Optional.
+  optional ContainmentLevelCode containment_level_code = 2;
+}
+  
+  // Allergen shown to the user on the MenuItem. An allergen relates to qualities
+// of food that causes allergic reactions.
+message Allergen {
+  // Type of allergen.
+  // Required.
+  AllergenTypeCode allergen_type_code = 1;
+
+  // Whether the MenuItem contains, may contain, or is free from this allergen.
+  // Defaults to contains.
+  // Optional.
+  optional ContainmentLevelCode containment_level_code = 2;
+}
+
+  // Allergen type derived from GS1: http://gs1.org/voc/AllergenTypeCode
+enum AllergenTypeCode {
+  // Do not use. The allergen type code is not explicitly specified.
+  ALLERGEN_TYPE_CODE_UNSPECIFIED = 0;
+  ALLERGEN_TYPE_CODE_ALMONDS = 1;
+  ALLERGEN_TYPE_CODE_ALPHA_ISOMETHYL_IONONE = 2;
+  ALLERGEN_TYPE_CODE_ALCOHOL = 3;
+  ALLERGEN_TYPE_CODE_AMYL_CINNAMAL = 4;
+  ALLERGEN_TYPE_CODE_ANISE_ALCOHOL = 5;
+  ALLERGEN_TYPE_CODE_BARLEY = 6;
+  ALLERGEN_TYPE_CODE_BENZYL_ALCOHOL = 7;
+  ALLERGEN_TYPE_CODE_BENZYL_BENZOATE = 8;
+  ALLERGEN_TYPE_CODE_BENZYL_CINNAMATE = 9;
+  ALLERGEN_TYPE_CODE_BENZYL_SALICYLATE = 10;
+  ALLERGEN_TYPE_CODE_BRAZIL_NUTS = 11;
+  ALLERGEN_TYPE_CODE_BUTYLPHENYL_METHYLPROPIONATE = 12;
+  ALLERGEN_TYPE_CODE_CARROTS = 13;
+  ALLERGEN_TYPE_CODE_CASHEW_NUTS = 14;
+  ALLERGEN_TYPE_CODE_CELERY = 15;
+  ALLERGEN_TYPE_CODE_CEREALS_CONTAINING_GLUTEN = 16;
+  ALLERGEN_TYPE_CODE_CINNAMAL = 17;
+  ALLERGEN_TYPE_CODE_CINNAMYL_ALCOHOL = 18;
+  ALLERGEN_TYPE_CODE_CITRAL = 19;
+  ALLERGEN_TYPE_CODE_CITRONELLOL = 20;
+  ALLERGEN_TYPE_CODE_COCOA = 21;
+  ALLERGEN_TYPE_CODE_CORIANDER = 22;
+  ALLERGEN_TYPE_CODE_CORN = 23;
+  ALLERGEN_TYPE_CODE_COUMARIN = 24;
+  ALLERGEN_TYPE_CODE_CRUSTACEANS = 25;
+  ALLERGEN_TYPE_CODE_EGGS = 26;
+  ALLERGEN_TYPE_CODE_EUGENOL = 27;
+  ALLERGEN_TYPE_CODE_EVERNIA_FURFURACEA = 28;
+  ALLERGEN_TYPE_CODE_EVERNIA_PRUNASTRI = 29;
+  ALLERGEN_TYPE_CODE_FARNESOL = 30;
+  ALLERGEN_TYPE_CODE_FISH = 31;
+  ALLERGEN_TYPE_CODE_GERANIOL = 32;
+  ALLERGEN_TYPE_CODE_GLUTEN = 33;
+  ALLERGEN_TYPE_CODE_HAZELNUTS = 34;
+  ALLERGEN_TYPE_CODE_HEXYL_CINNAMAL = 35;
+  ALLERGEN_TYPE_CODE_HYDROXYCITRONELLAL = 36;
+  ALLERGEN_TYPE_CODE_HYDROXYISOHEXYL_3_CYCLOHEXENE_CARBOXALDEHYDE_ISOEUGENOL_LIMONENE_LINAL =
+      37;
+  ALLERGEN_TYPE_CODE_KAMUT = 38;
+  ALLERGEN_TYPE_CODE_LACTOSE = 39;
+  ALLERGEN_TYPE_CODE_LUPINE = 40;
+  ALLERGEN_TYPE_CODE_MACADAMIA_NUTS = 41;
+  ALLERGEN_TYPE_CODE_METHYL_2_OCTYNOATE = 42;
+  ALLERGEN_TYPE_CODE_MILK = 43;
+  ALLERGEN_TYPE_CODE_MOLLUSCS = 44;
+  ALLERGEN_TYPE_CODE_MUSTARD = 45;
+  ALLERGEN_TYPE_CODE_NO_DECLARED_ALLERGENS = 46;
+  ALLERGEN_TYPE_CODE_OAT = 47;
+  ALLERGEN_TYPE_CODE_PEANUTS = 48;
+  ALLERGEN_TYPE_CODE_PEAS = 49;
+  ALLERGEN_TYPE_CODE_PECAN_NUTS = 50;
+  ALLERGEN_TYPE_CODE_PISTACHIOS = 51;
+  ALLERGEN_TYPE_CODE_POD_FRUITS = 52;
+  ALLERGEN_TYPE_CODE_QUEENSLAND_NUTS = 53;
+  ALLERGEN_TYPE_CODE_RYE = 54;
+  ALLERGEN_TYPE_CODE_SESAME_SEEDS = 55;
+  ALLERGEN_TYPE_CODE_SOYBEANS = 56;
+  ALLERGEN_TYPE_CODE_SPELT = 57;
+  ALLERGEN_TYPE_CODE_SULPHUR_DIOXIDE = 58;
+  ALLERGEN_TYPE_CODE_TREE_NUTS = 59;
+  ALLERGEN_TYPE_CODE_TREE_NUT_TRACES = 60;
+  ALLERGEN_TYPE_CODE_WALNUTS = 61;
+  ALLERGEN_TYPE_CODE_WHEAT = 62;
+}
+
+  // Partner provided deposit info to instruct the user how to deposit a food item
+// or bottle and the value of such deposit.
+message DepositInfo {
+  // The deposit strategy to employ, e.g. "reusable".
+  // Optional.
+  optional DepositCode deposit_code = 1;
+
+  // Value refunded for depositing the item properly.
+  // Optional.
+  google.type.Money deposit_value = 2;
+}
+
+  enum NutritionValueUnit {
+  // Do not use. The nutrition value unit is not explicitly set.
+  NUTRITION_VALUE_UNIT_UNSPECIFIED = 0;
+
+  // Units used to express the amount of energy in a menu item.
+  ENERGY_CALORIES = 1;
+  ENERGY_KILOJOULES = 2;
+
+  // Units used to express the amount in weight a substance is present in the
+  // menu item.
+  WEIGHT_MILLIGRAMS = 3;
+  WEIGHT_GRAMS = 4;
+}
+
+  // Indicates the level of containment a food item has of a certain attribute,
+// such as allergens or additives.
+enum ContainmentLevelCode {
+  // Do not use. The containment level code is not explicitly specified.
+  CONTAINMENT_LEVEL_CODE_UNSPECIFIED = 0;
+  CONTAINMENT_LEVEL_CODE_CONTAINS = 1;
+  CONTAINMENT_LEVEL_CODE_DOES_NOT_CONTAIN = 2;
+  CONTAINMENT_LEVEL_CODE_MAY_CONTAIN = 3;
+}
+
+  // Indicates how to properly deposit a food item or bottle.
+enum DepositCode {
+  // Do not use. The deposite code is not explicitly specified.
+  DEPOSIT_CODE_UNSPECIFIED = 0;
+  DEPOSIT_CODE_REUSABLE = 1;
+  DEPOSIT_CODE_RECYCLABLE = 2;
+}
diff --git a/menu-feed/proto/localized_text.proto b/menu-feed/proto/localized_text.proto
new file mode 100644
index 0000000..df7ebf2
--- /dev/null
+++ b/menu-feed/proto/localized_text.proto
@@ -0,0 +1,37 @@
+  // Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package google.type;
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/type/localized_text;localized_text";
+option java_multiple_files = true;
+option java_outer_classname = "LocalizedTextProto";
+option java_package = "com.google.type";
+option objc_class_prefix = "GTP";
+
+// Localized variant of a text in a particular language.
+message LocalizedText {
+  // Localized string in the language corresponding to `language_code' below.
+  string text = 1;
+
+  // The text's BCP-47 language code, such as "en-US" or "sr-Latn".
+  //
+  // For more information, see
+  // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
+  string language_code = 2;
+}
+
diff --git a/menu-feed/proto/money.proto b/menu-feed/proto/money.proto
new file mode 100644
index 0000000..dbd61d6
--- /dev/null
+++ b/menu-feed/proto/money.proto
@@ -0,0 +1,43 @@
+  // Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package google.type;
+
+option cc_enable_arenas = true;
+option go_package = "google.golang.org/genproto/googleapis/type/money;money";
+option java_multiple_files = true;
+option java_outer_classname = "MoneyProto";
+option java_package = "com.google.type";
+option objc_class_prefix = "GTP";
+
+// Represents an amount of money with its currency type.
+message Money {
+  // The three-letter currency code defined in ISO 4217.
+  string currency_code = 1;
+
+  // The whole units of the amount.
+  // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar.
+  int64 units = 2;
+
+  // Number of nano (10^-9) units of the amount.
+  // The value must be between -999,999,999 and +999,999,999 inclusive.
+  // If `units` is positive, `nanos` must be positive or zero.
+  // If `units` is zero, `nanos` can be positive, zero, or negative.
+  // If `units` is negative, `nanos` must be negative or zero.
+  // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
+  int32 nanos = 3;
+}
+
diff --git a/menu-feed/python/feed.py b/menu-feed/python/feed.py
new file mode 100644
index 0000000..33c5435
--- /dev/null
+++ b/menu-feed/python/feed.py
@@ -0,0 +1,68 @@
+"""Menu feed example used in
+
+https://developers.google.com/maps-booking/verticals/dining/guides/tutorials/tutorial-menu-feed-protos#python.
+"""
+import json
+from generated import food_menu_pb2
+from google.protobuf.json_format import MessageToDict
+
+# create feed
+feed = food_menu_pb2.FoodMenuFeed()
+
+# add a menu component to feed data
+menuComponent = feed.data.add()
+menuComponent.menu.menu_id = 'menu1'
+menuComponent.menu.merchant_ids.append('dining-1')
+menuDisplayName = menuComponent.menu.display_name.text.add()
+menuDisplayName.text = 'Menu'
+menuDisplayName.language_code = 'en-us'
+menuComponent.menu.language = 'en-us'
+menuComponent.menu.last_merchant_update_time.seconds = 1633621547
+
+for i in ['appetizers', 'dinner']:
+  menuComponent.menu.menu_section_ids.append(i)
+
+# add a menu section component to feed data
+sectionComponent = feed.data.add()
+sectionComponent.section.menu_section_id = 'appetizers'
+sectionDisplayName = sectionComponent.section.display_name.text.add()
+sectionDisplayName.text = 'Lunch Appetizers'
+sectionDisplayName.language_code = 'en-us'
+sectionComponent.section.menu_item_ids.append('breadsticks-sauce')
+
+# add a menu item component to feed data
+itemComponent = feed.data.add()
+itemComponent.item.menu_item_id = 'breadsticks-sauce'
+itemDisplayName = itemComponent.item.display_name.text.add()
+itemDisplayName.text = 'Breadsticks & Sauce'
+itemDisplayName.language_code = 'en-us'
+itemDescription = itemComponent.item.description.text.add()
+itemDescription.text = 'Breakfast basket w/ side of tomato sauce (size 6 or 12)'
+itemDescription.language_code = 'en-us'
+
+for i in ['breadstick-sm', 'breadstick-lg']:
+  itemComponent.item.menu_item_option_set.menu_item_option_ids.append(i)
+
+for i in [
+    'http://www.example.com/photos/breadsticks.jpg',
+    'http://www.example.com/photos/sauce.jpg',
+]:
+  itemImage = itemComponent.item.images.add()
+  itemImage.uri = i
+
+# add a menu item option component to feed data
+optionComponent = feed.data.add()
+optionComponent.option.menu_item_option_id: 'breadstick-sm'
+optionComponent.option.value.property_type = (
+    food_menu_pb2.MenuItemOptionProperty.PropertyType.SIZE
+)
+optionTextValue = optionComponent.option.value.text_val.text.add()
+optionTextValue.text = 'Small'
+optionTextValue.language_code = 'en-us'
+optionOffer = optionComponent.option.offer_set.offers.add()
+optionOffer.price.currency_code = 'USD'
+optionOffer.price.units = 8
+optionOffer.price.nanos = 0
+
+feedJSON = json.dumps(MessageToDict(feed, preserving_proto_field_name=True))
+print(feedJSON)
diff --git a/menu-feed/typescript/dist/feed.js b/menu-feed/typescript/dist/feed.js
new file mode 100644
index 0000000..7b199a6
--- /dev/null
+++ b/menu-feed/typescript/dist/feed.js
@@ -0,0 +1,56 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const food_menu_1 = require("./generated/food_menu");
+const menu = {
+    menu_id: 'menu1',
+    merchant_ids: ['dining-1'],
+    display_name: { text: [{ text: 'Menu', language_code: 'en-us' }] },
+    language: 'en-us',
+    menu_section_ids: ['appetizers', 'dinner'],
+    last_merchant_update_time: new Date()
+};
+const section = {
+    menu_section_id: 'appetizers',
+    display_name: { text: [{ text: 'Lunch Appetizers', language_code: 'en-us' }] },
+    menu_section_ids: ['breadsticks-sauce']
+};
+const item = {
+    menu_item_id: 'breadsticks-sauce',
+    display_name: { text: [{ text: 'Breadsticks & Sauce', language_code: 'en-us' }] },
+    description: {
+        text: [{
+                text: 'Breakfast basket w/ side of tomato sauce (size 6 or 12)',
+                language_code: 'en-us'
+            }]
+    },
+    menu_item_option_set: { menu_item_option_ids: ['breadstick-sm', 'breadstick-lg'] },
+    images: [
+        { uri: 'http://www.example.com/photos/breadsticks.jpg' },
+        { uri: 'http://www.example.com/photos/sauce.jpg' }
+    ]
+};
+const option = {
+    menu_item_option_id: 'breadstick-sm',
+    value: {
+        property_type: food_menu_1.MenuItemOptionProperty_PropertyType.SIZE,
+        text_val: {
+            text: [
+                { text: "Small", language_code: "en-us" }
+            ]
+        }
+    },
+    offer_set: {
+        offers: [{
+                price: {
+                    currency_code: "USD",
+                    units: 8,
+                    nanos: 0
+                }
+            }]
+    }
+};
+const feed = {
+    data: [{ menu }, { section }, { item }, { option }]
+};
+console.log(JSON.stringify(feed));
+//# sourceMappingURL=feed.js.map
\ No newline at end of file
diff --git a/menu-feed/typescript/dist/feed.js.map b/menu-feed/typescript/dist/feed.js.map
new file mode 100644
index 0000000..eb55789
--- /dev/null
+++ b/menu-feed/typescript/dist/feed.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"feed.js","sourceRoot":"","sources":["../src/feed.ts"],"names":[],"mappings":";;AAAA,qDAAqI;AAErI,MAAM,IAAI,GAAS;IACjB,OAAO,EAAE,OAAO;IAChB,YAAY,EAAE,CAAC,UAAU,CAAC;IAC1B,YAAY,EAAE,EAAC,IAAI,EAAE,CAAC,EAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAC,CAAC,EAAC;IAC9D,QAAQ,EAAE,OAAO;IACjB,gBAAgB,EAAE,CAAC,YAAY,EAAE,QAAQ,CAAC;IAC1C,yBAAyB,EAAE,IAAI,IAAI,EAAE;CACtC,CAAC;AAEF,MAAM,OAAO,GAAgB;IAC3B,eAAe,EAAE,YAAY;IAC7B,YAAY,EAAE,EAAC,IAAI,EAAE,CAAC,EAAC,IAAI,EAAE,kBAAkB,EAAE,aAAa,EAAE,OAAO,EAAC,CAAC,EAAC;IAC1E,gBAAgB,EAAE,CAAC,mBAAmB,CAAC;CACxC,CAAC;AAEF,MAAM,IAAI,GAAa;IACrB,YAAY,EAAE,mBAAmB;IACjC,YAAY,EAAE,EAAC,IAAI,EAAE,CAAC,EAAC,IAAI,EAAE,qBAAqB,EAAE,aAAa,EAAE,OAAO,EAAC,CAAC,EAAC;IAC7E,WAAW,EAAE;QACX,IAAI,EAAE,CAAC;gBACL,IAAI,EAAE,yDAAyD;gBAC/D,aAAa,EAAE,OAAO;aACvB,CAAC;KACH;IACD,oBAAoB,EAChB,EAAC,oBAAoB,EAAE,CAAC,eAAe,EAAE,eAAe,CAAC,EAAC;IAC9D,MAAM,EAAE;QACN,EAAC,GAAG,EAAE,+CAA+C,EAAC;QACtD,EAAC,GAAG,EAAE,yCAAyC,EAAC;KACjD;CACF,CAAC;AAEF,MAAM,MAAM,GAAmB;IAC7B,mBAAmB,EAAE,eAAe;IACpC,KAAK,EAAE;QACL,aAAa,EAAE,+CAAmC,CAAC,IAAI;QACvD,QAAQ,EAAE;YACR,IAAI,EAAE;gBACJ,EAAC,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAC;aACxC;SACD;KACH;IACD,SAAS,EAAE;QACT,MAAM,EAAE,CAAC;gBACP,KAAK,EAAE;oBACL,aAAa,EAAE,KAAK;oBACpB,KAAK,EAAE,CAAC;oBACR,KAAK,EAAE,CAAC;iBACT;aACF,CAAC;KACH;CACF,CAAC;AAEF,MAAM,IAAI,GAAiB;IACzB,IAAI,EAAE,CAAC,EAAC,IAAI,EAAC,EAAE,EAAC,OAAO,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,MAAM,EAAC,CAAC;CAC5C,CAAC;AAEF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC"}
\ No newline at end of file
diff --git a/menu-feed/typescript/package-lock.json b/menu-feed/typescript/package-lock.json
new file mode 100644
index 0000000..2f6ba0d
--- /dev/null
+++ b/menu-feed/typescript/package-lock.json
@@ -0,0 +1,380 @@
+{
+  "name": "typescript",
+  "version": "1.0.0",
+  "lockfileVersion": 2,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "typescript",
+      "version": "1.0.0",
+      "license": "ISC",
+      "dependencies": {
+        "google-protobuf": "^3.21.2",
+        "ts-proto": "^1.143.0"
+      },
+      "devDependencies": {
+        "typescript": "^4.9.5"
+      }
+    },
+    "node_modules/@protobufjs/aspromise": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+      "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
+    },
+    "node_modules/@protobufjs/base64": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+      "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+    },
+    "node_modules/@protobufjs/codegen": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+      "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+    },
+    "node_modules/@protobufjs/eventemitter": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+      "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
+    },
+    "node_modules/@protobufjs/fetch": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+      "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+      "dependencies": {
+        "@protobufjs/aspromise": "^1.1.1",
+        "@protobufjs/inquire": "^1.1.0"
+      }
+    },
+    "node_modules/@protobufjs/float": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+      "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
+    },
+    "node_modules/@protobufjs/inquire": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+      "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
+    },
+    "node_modules/@protobufjs/path": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+      "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
+    },
+    "node_modules/@protobufjs/pool": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+      "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
+    },
+    "node_modules/@protobufjs/utf8": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+      "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
+    },
+    "node_modules/@types/long": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
+      "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
+    },
+    "node_modules/@types/node": {
+      "version": "18.15.7",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.7.tgz",
+      "integrity": "sha512-LFmUbFunqmBn26wJZgZPYZPrDR1RwGOu2v79Mgcka1ndO6V0/cwjivPTc4yoK6n9kmw4/ls1r8cLrvh2iMibFA=="
+    },
+    "node_modules/@types/object-hash": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/@types/object-hash/-/object-hash-1.3.4.tgz",
+      "integrity": "sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA=="
+    },
+    "node_modules/case-anything": {
+      "version": "2.1.10",
+      "resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.10.tgz",
+      "integrity": "sha512-JczJwVrCP0jPKh05McyVsuOg6AYosrB9XWZKbQzXeDAm2ClE/PJE/BcrrQrVyGYH7Jg8V/LDupmyL4kFlVsVFQ==",
+      "engines": {
+        "node": ">=12.13"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/mesqueeb"
+      }
+    },
+    "node_modules/dataloader": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz",
+      "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw=="
+    },
+    "node_modules/detect-libc": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+      "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
+      "bin": {
+        "detect-libc": "bin/detect-libc.js"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/dprint-node": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/dprint-node/-/dprint-node-1.0.7.tgz",
+      "integrity": "sha512-NTZOW9A7ipb0n7z7nC3wftvsbceircwVHSgzobJsEQa+7RnOMbhrfX5IflA6CtC4GA63DSAiHYXa4JKEy9F7cA==",
+      "dependencies": {
+        "detect-libc": "^1.0.3"
+      }
+    },
+    "node_modules/google-protobuf": {
+      "version": "3.21.2",
+      "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz",
+      "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA=="
+    },
+    "node_modules/long": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+      "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+    },
+    "node_modules/object-hash": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz",
+      "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==",
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/protobufjs": {
+      "version": "6.11.3",
+      "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz",
+      "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==",
+      "hasInstallScript": true,
+      "dependencies": {
+        "@protobufjs/aspromise": "^1.1.2",
+        "@protobufjs/base64": "^1.1.2",
+        "@protobufjs/codegen": "^2.0.4",
+        "@protobufjs/eventemitter": "^1.1.0",
+        "@protobufjs/fetch": "^1.1.0",
+        "@protobufjs/float": "^1.0.2",
+        "@protobufjs/inquire": "^1.1.0",
+        "@protobufjs/path": "^1.1.2",
+        "@protobufjs/pool": "^1.1.0",
+        "@protobufjs/utf8": "^1.1.0",
+        "@types/long": "^4.0.1",
+        "@types/node": ">=13.7.0",
+        "long": "^4.0.0"
+      },
+      "bin": {
+        "pbjs": "bin/pbjs",
+        "pbts": "bin/pbts"
+      }
+    },
+    "node_modules/ts-poet": {
+      "version": "6.4.1",
+      "resolved": "https://registry.npmjs.org/ts-poet/-/ts-poet-6.4.1.tgz",
+      "integrity": "sha512-AjZEs4h2w4sDfwpHMxQKHrTlNh2wRbM5NRXmLz0RiH+yPGtSQFbe9hBpNocU8vqVNgfh0BIOiXR80xDz3kKxUQ==",
+      "dependencies": {
+        "dprint-node": "^1.0.7"
+      }
+    },
+    "node_modules/ts-proto": {
+      "version": "1.143.0",
+      "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-1.143.0.tgz",
+      "integrity": "sha512-a6pxp7y/R6PlaB+4adDVVTTZPHfNt4QLlm4wU8zBn5yXHbofBOIKLJ5bymwl0nizOAnuSMqt0GllOSAUnzkvYw==",
+      "dependencies": {
+        "@types/object-hash": "^1.3.0",
+        "case-anything": "^2.1.10",
+        "dataloader": "^1.4.0",
+        "object-hash": "^1.3.1",
+        "protobufjs": "^6.11.3",
+        "ts-poet": "^6.4.1",
+        "ts-proto-descriptors": "1.7.1"
+      },
+      "bin": {
+        "protoc-gen-ts_proto": "protoc-gen-ts_proto"
+      }
+    },
+    "node_modules/ts-proto-descriptors": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/ts-proto-descriptors/-/ts-proto-descriptors-1.7.1.tgz",
+      "integrity": "sha512-oIKUh3K4Xts4v29USGLfUG+2mEk32MsqpgZAOUyUlkrcIdv34yE+k2oZ2Nzngm6cV/JgFdOxRCqeyvmWHuYAyw==",
+      "dependencies": {
+        "long": "^4.0.0",
+        "protobufjs": "^6.8.8"
+      }
+    },
+    "node_modules/typescript": {
+      "version": "4.9.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
+      "dev": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=4.2.0"
+      }
+    }
+  },
+  "dependencies": {
+    "@protobufjs/aspromise": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+      "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
+    },
+    "@protobufjs/base64": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+      "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+    },
+    "@protobufjs/codegen": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+      "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+    },
+    "@protobufjs/eventemitter": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+      "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
+    },
+    "@protobufjs/fetch": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+      "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+      "requires": {
+        "@protobufjs/aspromise": "^1.1.1",
+        "@protobufjs/inquire": "^1.1.0"
+      }
+    },
+    "@protobufjs/float": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+      "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
+    },
+    "@protobufjs/inquire": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+      "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
+    },
+    "@protobufjs/path": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+      "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
+    },
+    "@protobufjs/pool": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+      "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
+    },
+    "@protobufjs/utf8": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+      "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
+    },
+    "@types/long": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
+      "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
+    },
+    "@types/node": {
+      "version": "18.15.7",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.7.tgz",
+      "integrity": "sha512-LFmUbFunqmBn26wJZgZPYZPrDR1RwGOu2v79Mgcka1ndO6V0/cwjivPTc4yoK6n9kmw4/ls1r8cLrvh2iMibFA=="
+    },
+    "@types/object-hash": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/@types/object-hash/-/object-hash-1.3.4.tgz",
+      "integrity": "sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA=="
+    },
+    "case-anything": {
+      "version": "2.1.10",
+      "resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.10.tgz",
+      "integrity": "sha512-JczJwVrCP0jPKh05McyVsuOg6AYosrB9XWZKbQzXeDAm2ClE/PJE/BcrrQrVyGYH7Jg8V/LDupmyL4kFlVsVFQ=="
+    },
+    "dataloader": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz",
+      "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw=="
+    },
+    "detect-libc": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+      "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="
+    },
+    "dprint-node": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/dprint-node/-/dprint-node-1.0.7.tgz",
+      "integrity": "sha512-NTZOW9A7ipb0n7z7nC3wftvsbceircwVHSgzobJsEQa+7RnOMbhrfX5IflA6CtC4GA63DSAiHYXa4JKEy9F7cA==",
+      "requires": {
+        "detect-libc": "^1.0.3"
+      }
+    },
+    "google-protobuf": {
+      "version": "3.21.2",
+      "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz",
+      "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA=="
+    },
+    "long": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+      "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+    },
+    "object-hash": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz",
+      "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA=="
+    },
+    "protobufjs": {
+      "version": "6.11.3",
+      "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz",
+      "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==",
+      "requires": {
+        "@protobufjs/aspromise": "^1.1.2",
+        "@protobufjs/base64": "^1.1.2",
+        "@protobufjs/codegen": "^2.0.4",
+        "@protobufjs/eventemitter": "^1.1.0",
+        "@protobufjs/fetch": "^1.1.0",
+        "@protobufjs/float": "^1.0.2",
+        "@protobufjs/inquire": "^1.1.0",
+        "@protobufjs/path": "^1.1.2",
+        "@protobufjs/pool": "^1.1.0",
+        "@protobufjs/utf8": "^1.1.0",
+        "@types/long": "^4.0.1",
+        "@types/node": ">=13.7.0",
+        "long": "^4.0.0"
+      }
+    },
+    "ts-poet": {
+      "version": "6.4.1",
+      "resolved": "https://registry.npmjs.org/ts-poet/-/ts-poet-6.4.1.tgz",
+      "integrity": "sha512-AjZEs4h2w4sDfwpHMxQKHrTlNh2wRbM5NRXmLz0RiH+yPGtSQFbe9hBpNocU8vqVNgfh0BIOiXR80xDz3kKxUQ==",
+      "requires": {
+        "dprint-node": "^1.0.7"
+      }
+    },
+    "ts-proto": {
+      "version": "1.143.0",
+      "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-1.143.0.tgz",
+      "integrity": "sha512-a6pxp7y/R6PlaB+4adDVVTTZPHfNt4QLlm4wU8zBn5yXHbofBOIKLJ5bymwl0nizOAnuSMqt0GllOSAUnzkvYw==",
+      "requires": {
+        "@types/object-hash": "^1.3.0",
+        "case-anything": "^2.1.10",
+        "dataloader": "^1.4.0",
+        "object-hash": "^1.3.1",
+        "protobufjs": "^6.11.3",
+        "ts-poet": "^6.4.1",
+        "ts-proto-descriptors": "1.7.1"
+      }
+    },
+    "ts-proto-descriptors": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/ts-proto-descriptors/-/ts-proto-descriptors-1.7.1.tgz",
+      "integrity": "sha512-oIKUh3K4Xts4v29USGLfUG+2mEk32MsqpgZAOUyUlkrcIdv34yE+k2oZ2Nzngm6cV/JgFdOxRCqeyvmWHuYAyw==",
+      "requires": {
+        "long": "^4.0.0",
+        "protobufjs": "^6.8.8"
+      }
+    },
+    "typescript": {
+      "version": "4.9.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
+      "dev": true
+    }
+  }
+}
diff --git a/menu-feed/typescript/package.json b/menu-feed/typescript/package.json
new file mode 100644
index 0000000..c43360d
--- /dev/null
+++ b/menu-feed/typescript/package.json
@@ -0,0 +1,19 @@
+{
+  "name": "typescript",
+  "version": "1.0.0",
+  "description": "",
+  "main": "index.js",
+  "scripts": {
+    "build": "tsc --build",
+    "clean": "tsc --build --clean"
+  },
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "google-protobuf": "^3.21.2",
+    "ts-proto": "^1.143.0"
+  },
+  "devDependencies": {
+    "typescript": "^4.9.5"
+  }
+}
diff --git a/menu-feed/typescript/src/feed.ts b/menu-feed/typescript/src/feed.ts
new file mode 100644
index 0000000..8e91388
--- /dev/null
+++ b/menu-feed/typescript/src/feed.ts
@@ -0,0 +1,60 @@
+import {FoodMenuFeed, Menu, MenuItem, MenuSection, MenuItemOption, MenuItemOptionProperty_PropertyType} from './generated/food_menu';
+
+const menu: Menu = {
+  menu_id: 'menu1',
+  merchant_ids: ['dining-1'],
+  display_name: {text: [{text: 'Menu', language_code: 'en-us'}]},
+  language: 'en-us',
+  menu_section_ids: ['appetizers', 'dinner'],
+  last_merchant_update_time: new Date()
+};
+
+const section: MenuSection = {
+  menu_section_id: 'appetizers',
+  display_name: {text: [{text: 'Lunch Appetizers', language_code: 'en-us'}]},
+  menu_section_ids: ['breadsticks-sauce']
+};
+
+const item: MenuItem = {
+  menu_item_id: 'breadsticks-sauce',
+  display_name: {text: [{text: 'Breadsticks & Sauce', language_code: 'en-us'}]},
+  description: {
+    text: [{
+      text: 'Breakfast basket w/ side of tomato sauce (size 6 or 12)',
+      language_code: 'en-us'
+    }]
+  },
+  menu_item_option_set:
+      {menu_item_option_ids: ['breadstick-sm', 'breadstick-lg']},
+  images: [
+    {uri: 'http://www.example.com/photos/breadsticks.jpg'},
+    {uri: 'http://www.example.com/photos/sauce.jpg'}
+  ]
+};
+
+const option: MenuItemOption = {
+  menu_item_option_id: 'breadstick-sm',
+  value: {
+    property_type: MenuItemOptionProperty_PropertyType.SIZE,
+    text_val: {
+      text: [
+        {text: "Small", language_code: "en-us"}
+      ]
+     }
+  },
+  offer_set: {
+    offers: [{
+      price: {
+        currency_code: "USD",
+        units: 8,
+        nanos: 0
+      }
+    }]
+  }
+};
+
+const feed: FoodMenuFeed = {
+  data: [{menu}, {section}, {item}, {option}]
+};
+
+console.log(JSON.stringify(feed));
diff --git a/menu-feed/typescript/tsconfig.json b/menu-feed/typescript/tsconfig.json
new file mode 100644
index 0000000..b9cbb66
--- /dev/null
+++ b/menu-feed/typescript/tsconfig.json
@@ -0,0 +1,15 @@
+{
+  "include": ["src/**/*"],
+  "compilerOptions": {
+    "outDir": "dist",
+    "rootDir": "src",
+    "allowJs": true,
+    "target": "ES2020",
+    "module": "commonjs",
+    "declaration": false,
+    "sourceMap": true,
+    "strict": true,
+    "esModuleInterop": true,
+    "forceConsistentCasingInFileNames": true
+  }
+}
\ No newline at end of file
