diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0f245e8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+node_modules
+target
+bazel-*
+generated
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
