Revert "Enable the ignore_unknown_field option in the Ruby unmarshal options" (#5511)

diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt
index 8927032..53b4970 100644
--- a/conformance/failure_list_ruby.txt
+++ b/conformance/failure_list_ruby.txt
@@ -5,6 +5,8 @@
 Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput
 Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator
 Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator
+Recommended.Proto3.JsonInput.DurationHas9FractionalDigits.Validator
+Recommended.Proto3.JsonInput.DurationHasZeroFractionalDigit.Validator
 Recommended.Proto3.JsonInput.Int64FieldBeString.Validator
 Recommended.Proto3.JsonInput.MapFieldValueIsNull
 Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull
@@ -15,6 +17,9 @@
 Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate
 Recommended.Proto3.JsonInput.TimestampHas3FractionalDigits.Validator
 Recommended.Proto3.JsonInput.TimestampHas6FractionalDigits.Validator
+Recommended.Proto3.JsonInput.TimestampHas9FractionalDigits.Validator
+Recommended.Proto3.JsonInput.TimestampHasZeroFractionalDigit.Validator
+Recommended.Proto3.JsonInput.TimestampZeroNormalized.Validator
 Recommended.Proto3.JsonInput.Uint64FieldBeString.Validator
 Required.DurationProtoInputTooLarge.JsonOutput
 Required.DurationProtoInputTooSmall.JsonOutput
@@ -43,8 +48,12 @@
 Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
 Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
 Required.Proto3.JsonInput.DoubleFieldNan.JsonOutput
+Required.Proto3.JsonInput.DurationMaxValue.JsonOutput
+Required.Proto3.JsonInput.DurationMaxValue.ProtobufOutput
 Required.Proto3.JsonInput.DurationMinValue.JsonOutput
+Required.Proto3.JsonInput.DurationMinValue.ProtobufOutput
 Required.Proto3.JsonInput.DurationRepeatedValue.JsonOutput
+Required.Proto3.JsonInput.DurationRepeatedValue.ProtobufOutput
 Required.Proto3.JsonInput.FieldMask.JsonOutput
 Required.Proto3.JsonInput.FieldMask.ProtobufOutput
 Required.Proto3.JsonInput.FloatFieldInfinity.JsonOutput
@@ -52,32 +61,71 @@
 Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput
 Required.Proto3.JsonInput.OneofFieldDuplicate
 Required.Proto3.JsonInput.OptionalBoolWrapper.JsonOutput
+Required.Proto3.JsonInput.OptionalBoolWrapper.ProtobufOutput
 Required.Proto3.JsonInput.OptionalBytesWrapper.JsonOutput
+Required.Proto3.JsonInput.OptionalBytesWrapper.ProtobufOutput
 Required.Proto3.JsonInput.OptionalDoubleWrapper.JsonOutput
+Required.Proto3.JsonInput.OptionalDoubleWrapper.ProtobufOutput
 Required.Proto3.JsonInput.OptionalFloatWrapper.JsonOutput
+Required.Proto3.JsonInput.OptionalFloatWrapper.ProtobufOutput
 Required.Proto3.JsonInput.OptionalInt32Wrapper.JsonOutput
+Required.Proto3.JsonInput.OptionalInt32Wrapper.ProtobufOutput
 Required.Proto3.JsonInput.OptionalInt64Wrapper.JsonOutput
+Required.Proto3.JsonInput.OptionalInt64Wrapper.ProtobufOutput
 Required.Proto3.JsonInput.OptionalStringWrapper.JsonOutput
+Required.Proto3.JsonInput.OptionalStringWrapper.ProtobufOutput
 Required.Proto3.JsonInput.OptionalUint32Wrapper.JsonOutput
+Required.Proto3.JsonInput.OptionalUint32Wrapper.ProtobufOutput
 Required.Proto3.JsonInput.OptionalUint64Wrapper.JsonOutput
+Required.Proto3.JsonInput.OptionalUint64Wrapper.ProtobufOutput
 Required.Proto3.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
 Required.Proto3.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
 Required.Proto3.JsonInput.RepeatedBoolWrapper.JsonOutput
+Required.Proto3.JsonInput.RepeatedBoolWrapper.ProtobufOutput
 Required.Proto3.JsonInput.RepeatedBytesWrapper.JsonOutput
+Required.Proto3.JsonInput.RepeatedBytesWrapper.ProtobufOutput
 Required.Proto3.JsonInput.RepeatedDoubleWrapper.JsonOutput
+Required.Proto3.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
 Required.Proto3.JsonInput.RepeatedFloatWrapper.JsonOutput
+Required.Proto3.JsonInput.RepeatedFloatWrapper.ProtobufOutput
 Required.Proto3.JsonInput.RepeatedInt32Wrapper.JsonOutput
+Required.Proto3.JsonInput.RepeatedInt32Wrapper.ProtobufOutput
 Required.Proto3.JsonInput.RepeatedInt64Wrapper.JsonOutput
+Required.Proto3.JsonInput.RepeatedInt64Wrapper.ProtobufOutput
 Required.Proto3.JsonInput.RepeatedStringWrapper.JsonOutput
+Required.Proto3.JsonInput.RepeatedStringWrapper.ProtobufOutput
 Required.Proto3.JsonInput.RepeatedUint32Wrapper.JsonOutput
+Required.Proto3.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
 Required.Proto3.JsonInput.RepeatedUint64Wrapper.JsonOutput
+Required.Proto3.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
 Required.Proto3.JsonInput.StringFieldSurrogatePair.JsonOutput
 Required.Proto3.JsonInput.StringFieldSurrogatePair.ProtobufOutput
-Required.Proto3.JsonInput.TimestampJsonInputTooSmall
+Required.Proto3.JsonInput.Struct.JsonOutput
+Required.Proto3.JsonInput.Struct.ProtobufOutput
+Required.Proto3.JsonInput.TimestampMaxValue.JsonOutput
+Required.Proto3.JsonInput.TimestampMaxValue.ProtobufOutput
 Required.Proto3.JsonInput.TimestampMinValue.JsonOutput
 Required.Proto3.JsonInput.TimestampMinValue.ProtobufOutput
 Required.Proto3.JsonInput.TimestampRepeatedValue.JsonOutput
 Required.Proto3.JsonInput.TimestampRepeatedValue.ProtobufOutput
+Required.Proto3.JsonInput.TimestampWithNegativeOffset.JsonOutput
+Required.Proto3.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
+Required.Proto3.JsonInput.TimestampWithPositiveOffset.JsonOutput
+Required.Proto3.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
+Required.Proto3.JsonInput.ValueAcceptBool.JsonOutput
+Required.Proto3.JsonInput.ValueAcceptBool.ProtobufOutput
+Required.Proto3.JsonInput.ValueAcceptFloat.JsonOutput
+Required.Proto3.JsonInput.ValueAcceptFloat.ProtobufOutput
+Required.Proto3.JsonInput.ValueAcceptInteger.JsonOutput
+Required.Proto3.JsonInput.ValueAcceptInteger.ProtobufOutput
+Required.Proto3.JsonInput.ValueAcceptList.JsonOutput
+Required.Proto3.JsonInput.ValueAcceptList.ProtobufOutput
+Required.Proto3.JsonInput.ValueAcceptNull.JsonOutput
+Required.Proto3.JsonInput.ValueAcceptNull.ProtobufOutput
+Required.Proto3.JsonInput.ValueAcceptObject.JsonOutput
+Required.Proto3.JsonInput.ValueAcceptObject.ProtobufOutput
+Required.Proto3.JsonInput.ValueAcceptString.JsonOutput
+Required.Proto3.JsonInput.ValueAcceptString.ProtobufOutput
 Required.Proto3.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
 Required.Proto3.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
 Required.Proto3.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
diff --git a/ruby/ext/google/protobuf_c/encode_decode.c b/ruby/ext/google/protobuf_c/encode_decode.c
index a14f0bc..0c5a74a 100644
--- a/ruby/ext/google/protobuf_c/encode_decode.c
+++ b/ruby/ext/google/protobuf_c/encode_decode.c
@@ -891,38 +891,19 @@
 
 /*
  * call-seq:
- *     MessageClass.decode_json(data, options = {}) => message
+ *     MessageClass.decode_json(data) => message
  *
  * Decodes the given data (as a string containing bytes in protocol buffers wire
  * format) under the interpretration given by this message class's definition
  * and returns a message object with the corresponding field values.
- *
- * @param options [Hash] options for the decoder
- *   ignore_unknown_fields: set true to ignore unknown fields (default is to raise an error)
  */
-VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
+VALUE Message_decode_json(VALUE klass, VALUE data) {
   VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
   Descriptor* desc = ruby_to_Descriptor(descriptor);
   VALUE msgklass = Descriptor_msgclass(descriptor);
   VALUE msg_rb;
-  VALUE data = argv[0];
-  VALUE ignore_unknown_fields = Qfalse;
   MessageHeader* msg;
 
-  if (argc < 1 || argc > 2) {
-    rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
-  }
-
-  if (argc == 2) {
-    VALUE hash_args = argv[1];
-    if (TYPE(hash_args) != T_HASH) {
-      rb_raise(rb_eArgError, "Expected hash arguments.");
-    }
-
-    ignore_unknown_fields = rb_hash_lookup2(
-        hash_args, ID2SYM(rb_intern("ignore_unknown_fields")), Qfalse);
-  }
-
   if (TYPE(data) != T_STRING) {
     rb_raise(rb_eArgError, "Expected string for JSON data.");
   }
@@ -941,7 +922,7 @@
     stackenv_init(&se, "Error occurred during parsing: %s");
 
     upb_sink_reset(&sink, get_fill_handlers(desc), msg);
-    parser = upb_json_parser_create(&se.env, method, &sink, ignore_unknown_fields);
+    parser = upb_json_parser_create(&se.env, method, &sink);
     upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
                       upb_json_parser_input(parser));
 
@@ -1329,12 +1310,9 @@
 
 /*
  * call-seq:
- *     MessageClass.encode_json(msg, options = {}) => json_string
+ *     MessageClass.encode_json(msg) => json_string
  *
  * Encodes the given message object into its serialized JSON representation.
- * @param options [Hash] options for the decoder
- *  preserve_proto_fieldnames: set true to use original fieldnames (default is to camelCase)
- *  emit_defaults: set true to emit 0/false values (default is to omit them)
  */
 VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
   VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c
index fd123ae..b1d6a5e 100644
--- a/ruby/ext/google/protobuf_c/message.c
+++ b/ruby/ext/google/protobuf_c/message.c
@@ -628,7 +628,7 @@
   rb_define_method(klass, "[]=", Message_index_set, 2);
   rb_define_singleton_method(klass, "decode", Message_decode, 1);
   rb_define_singleton_method(klass, "encode", Message_encode, 1);
-  rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1);
+  rb_define_singleton_method(klass, "decode_json", Message_decode_json, 1);
   rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1);
   rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0);
 
diff --git a/ruby/ext/google/protobuf_c/protobuf.h b/ruby/ext/google/protobuf_c/protobuf.h
index 616947c..0aa385a 100644
--- a/ruby/ext/google/protobuf_c/protobuf.h
+++ b/ruby/ext/google/protobuf_c/protobuf.h
@@ -570,7 +570,7 @@
 VALUE Message_descriptor(VALUE klass);
 VALUE Message_decode(VALUE klass, VALUE data);
 VALUE Message_encode(VALUE klass, VALUE msg_rb);
-VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass);
+VALUE Message_decode_json(VALUE klass, VALUE data);
 VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass);
 
 VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb);
diff --git a/ruby/ext/google/protobuf_c/upb.c b/ruby/ext/google/protobuf_c/upb.c
index 049e2bb..c02a5ce 100644
--- a/ruby/ext/google/protobuf_c/upb.c
+++ b/ruby/ext/google/protobuf_c/upb.c
@@ -1,506 +1,9 @@
 // Amalgamated source file
 #include "upb.h"
 
-#if UINTPTR_MAX == 0xffffffff
-#define UPB_SIZE(size32, size64) size32
-#else
-#define UPB_SIZE(size32, size64) size64
-#endif
-
-#define UPB_FIELD_AT(msg, fieldtype, offset) \
-  *(fieldtype*)((const char*)(msg) + offset)
-
-#define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
-  UPB_FIELD_AT(msg, int, case_offset) == case_val                              \
-      ? UPB_FIELD_AT(msg, fieldtype, offset)                                   \
-      : default
-
-#define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
-  UPB_FIELD_AT(msg, int, case_offset) = case_val;                             \
-  UPB_FIELD_AT(msg, fieldtype, offset) = value;
-/* This file was generated by upbc (the upb compiler) from the input
- * file:
- *
- *     google/protobuf/descriptor.proto
- *
- * Do not edit -- your changes will be discarded when the file is
- * regenerated. */
-
-#include <stddef.h>
-
-
-static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1] = {
-  &google_protobuf_FileDescriptorProto_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
-};
-
-const upb_msglayout google_protobuf_FileDescriptorSet_msginit = {
-  &google_protobuf_FileDescriptorSet_submsgs[0],
-  &google_protobuf_FileDescriptorSet__fields[0],
-  UPB_SIZE(4, 8), 1, false,
-};
-
-static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = {
-  &google_protobuf_DescriptorProto_msginit,
-  &google_protobuf_EnumDescriptorProto_msginit,
-  &google_protobuf_FieldDescriptorProto_msginit,
-  &google_protobuf_FileOptions_msginit,
-  &google_protobuf_ServiceDescriptorProto_msginit,
-  &google_protobuf_SourceCodeInfo_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = {
-  {1, UPB_SIZE(8, 16), 1, 0, 9, 1},
-  {2, UPB_SIZE(16, 32), 2, 0, 9, 1},
-  {3, UPB_SIZE(40, 80), 0, 0, 9, 3},
-  {4, UPB_SIZE(44, 88), 0, 0, 11, 3},
-  {5, UPB_SIZE(48, 96), 0, 1, 11, 3},
-  {6, UPB_SIZE(52, 104), 0, 4, 11, 3},
-  {7, UPB_SIZE(56, 112), 0, 2, 11, 3},
-  {8, UPB_SIZE(32, 64), 4, 3, 11, 1},
-  {9, UPB_SIZE(36, 72), 5, 5, 11, 1},
-  {10, UPB_SIZE(60, 120), 0, 0, 5, 3},
-  {11, UPB_SIZE(64, 128), 0, 0, 5, 3},
-  {12, UPB_SIZE(24, 48), 3, 0, 9, 1},
-};
-
-const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
-  &google_protobuf_FileDescriptorProto_submsgs[0],
-  &google_protobuf_FileDescriptorProto__fields[0],
-  UPB_SIZE(72, 144), 12, false,
-};
-
-static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[8] = {
-  &google_protobuf_DescriptorProto_msginit,
-  &google_protobuf_DescriptorProto_ExtensionRange_msginit,
-  &google_protobuf_DescriptorProto_ReservedRange_msginit,
-  &google_protobuf_EnumDescriptorProto_msginit,
-  &google_protobuf_FieldDescriptorProto_msginit,
-  &google_protobuf_MessageOptions_msginit,
-  &google_protobuf_OneofDescriptorProto_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = {
-  {1, UPB_SIZE(8, 16), 1, 0, 9, 1},
-  {2, UPB_SIZE(20, 40), 0, 4, 11, 3},
-  {3, UPB_SIZE(24, 48), 0, 0, 11, 3},
-  {4, UPB_SIZE(28, 56), 0, 3, 11, 3},
-  {5, UPB_SIZE(32, 64), 0, 1, 11, 3},
-  {6, UPB_SIZE(36, 72), 0, 4, 11, 3},
-  {7, UPB_SIZE(16, 32), 2, 5, 11, 1},
-  {8, UPB_SIZE(40, 80), 0, 6, 11, 3},
-  {9, UPB_SIZE(44, 88), 0, 2, 11, 3},
-  {10, UPB_SIZE(48, 96), 0, 0, 9, 3},
-};
-
-const upb_msglayout google_protobuf_DescriptorProto_msginit = {
-  &google_protobuf_DescriptorProto_submsgs[0],
-  &google_protobuf_DescriptorProto__fields[0],
-  UPB_SIZE(56, 112), 10, false,
-};
-
-static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
-  &google_protobuf_ExtensionRangeOptions_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = {
-  {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
-  {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
-  {3, UPB_SIZE(12, 16), 3, 0, 11, 1},
-};
-
-const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = {
-  &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0],
-  &google_protobuf_DescriptorProto_ExtensionRange__fields[0],
-  UPB_SIZE(16, 24), 3, false,
-};
-
-static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
-  {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
-  {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
-};
-
-const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = {
-  NULL,
-  &google_protobuf_DescriptorProto_ReservedRange__fields[0],
-  UPB_SIZE(12, 12), 2, false,
-};
-
-static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = {
-  &google_protobuf_UninterpretedOption_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1] = {
-  {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
-};
-
-const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = {
-  &google_protobuf_ExtensionRangeOptions_submsgs[0],
-  &google_protobuf_ExtensionRangeOptions__fields[0],
-  UPB_SIZE(4, 8), 1, false,
-};
-
-static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = {
-  &google_protobuf_FieldOptions_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[10] = {
-  {1, UPB_SIZE(32, 32), 5, 0, 9, 1},
-  {2, UPB_SIZE(40, 48), 6, 0, 9, 1},
-  {3, UPB_SIZE(24, 24), 3, 0, 5, 1},
-  {4, UPB_SIZE(8, 8), 1, 0, 14, 1},
-  {5, UPB_SIZE(16, 16), 2, 0, 14, 1},
-  {6, UPB_SIZE(48, 64), 7, 0, 9, 1},
-  {7, UPB_SIZE(56, 80), 8, 0, 9, 1},
-  {8, UPB_SIZE(72, 112), 10, 0, 11, 1},
-  {9, UPB_SIZE(28, 28), 4, 0, 5, 1},
-  {10, UPB_SIZE(64, 96), 9, 0, 9, 1},
-};
-
-const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
-  &google_protobuf_FieldDescriptorProto_submsgs[0],
-  &google_protobuf_FieldDescriptorProto__fields[0],
-  UPB_SIZE(80, 128), 10, false,
-};
-
-static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = {
-  &google_protobuf_OneofOptions_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = {
-  {1, UPB_SIZE(8, 16), 1, 0, 9, 1},
-  {2, UPB_SIZE(16, 32), 2, 0, 11, 1},
-};
-
-const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = {
-  &google_protobuf_OneofDescriptorProto_submsgs[0],
-  &google_protobuf_OneofDescriptorProto__fields[0],
-  UPB_SIZE(24, 48), 2, false,
-};
-
-static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = {
-  &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit,
-  &google_protobuf_EnumOptions_msginit,
-  &google_protobuf_EnumValueDescriptorProto_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = {
-  {1, UPB_SIZE(8, 16), 1, 0, 9, 1},
-  {2, UPB_SIZE(20, 40), 0, 2, 11, 3},
-  {3, UPB_SIZE(16, 32), 2, 1, 11, 1},
-  {4, UPB_SIZE(24, 48), 0, 0, 11, 3},
-  {5, UPB_SIZE(28, 56), 0, 0, 9, 3},
-};
-
-const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
-  &google_protobuf_EnumDescriptorProto_submsgs[0],
-  &google_protobuf_EnumDescriptorProto__fields[0],
-  UPB_SIZE(32, 64), 5, false,
-};
-
-static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
-  {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
-  {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
-};
-
-const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
-  NULL,
-  &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
-  UPB_SIZE(12, 12), 2, false,
-};
-
-static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
-  &google_protobuf_EnumValueOptions_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = {
-  {1, UPB_SIZE(8, 16), 2, 0, 9, 1},
-  {2, UPB_SIZE(4, 4), 1, 0, 5, 1},
-  {3, UPB_SIZE(16, 32), 3, 0, 11, 1},
-};
-
-const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = {
-  &google_protobuf_EnumValueDescriptorProto_submsgs[0],
-  &google_protobuf_EnumValueDescriptorProto__fields[0],
-  UPB_SIZE(24, 48), 3, false,
-};
-
-static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = {
-  &google_protobuf_MethodDescriptorProto_msginit,
-  &google_protobuf_ServiceOptions_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = {
-  {1, UPB_SIZE(8, 16), 1, 0, 9, 1},
-  {2, UPB_SIZE(20, 40), 0, 0, 11, 3},
-  {3, UPB_SIZE(16, 32), 2, 1, 11, 1},
-};
-
-const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = {
-  &google_protobuf_ServiceDescriptorProto_submsgs[0],
-  &google_protobuf_ServiceDescriptorProto__fields[0],
-  UPB_SIZE(24, 48), 3, false,
-};
-
-static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = {
-  &google_protobuf_MethodOptions_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = {
-  {1, UPB_SIZE(8, 16), 3, 0, 9, 1},
-  {2, UPB_SIZE(16, 32), 4, 0, 9, 1},
-  {3, UPB_SIZE(24, 48), 5, 0, 9, 1},
-  {4, UPB_SIZE(32, 64), 6, 0, 11, 1},
-  {5, UPB_SIZE(1, 1), 1, 0, 8, 1},
-  {6, UPB_SIZE(2, 2), 2, 0, 8, 1},
-};
-
-const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = {
-  &google_protobuf_MethodDescriptorProto_submsgs[0],
-  &google_protobuf_MethodDescriptorProto__fields[0],
-  UPB_SIZE(40, 80), 6, false,
-};
-
-static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
-  &google_protobuf_UninterpretedOption_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_FileOptions__fields[19] = {
-  {1, UPB_SIZE(32, 32), 11, 0, 9, 1},
-  {8, UPB_SIZE(40, 48), 12, 0, 9, 1},
-  {9, UPB_SIZE(8, 8), 1, 0, 14, 1},
-  {10, UPB_SIZE(16, 16), 2, 0, 8, 1},
-  {11, UPB_SIZE(48, 64), 13, 0, 9, 1},
-  {16, UPB_SIZE(17, 17), 3, 0, 8, 1},
-  {17, UPB_SIZE(18, 18), 4, 0, 8, 1},
-  {18, UPB_SIZE(19, 19), 5, 0, 8, 1},
-  {20, UPB_SIZE(20, 20), 6, 0, 8, 1},
-  {23, UPB_SIZE(21, 21), 7, 0, 8, 1},
-  {27, UPB_SIZE(22, 22), 8, 0, 8, 1},
-  {31, UPB_SIZE(23, 23), 9, 0, 8, 1},
-  {36, UPB_SIZE(56, 80), 14, 0, 9, 1},
-  {37, UPB_SIZE(64, 96), 15, 0, 9, 1},
-  {39, UPB_SIZE(72, 112), 16, 0, 9, 1},
-  {40, UPB_SIZE(80, 128), 17, 0, 9, 1},
-  {41, UPB_SIZE(88, 144), 18, 0, 9, 1},
-  {42, UPB_SIZE(24, 24), 10, 0, 8, 1},
-  {999, UPB_SIZE(96, 160), 0, 0, 11, 3},
-};
-
-const upb_msglayout google_protobuf_FileOptions_msginit = {
-  &google_protobuf_FileOptions_submsgs[0],
-  &google_protobuf_FileOptions__fields[0],
-  UPB_SIZE(104, 176), 19, false,
-};
-
-static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = {
-  &google_protobuf_UninterpretedOption_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = {
-  {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
-  {2, UPB_SIZE(2, 2), 2, 0, 8, 1},
-  {3, UPB_SIZE(3, 3), 3, 0, 8, 1},
-  {7, UPB_SIZE(4, 4), 4, 0, 8, 1},
-  {999, UPB_SIZE(8, 8), 0, 0, 11, 3},
-};
-
-const upb_msglayout google_protobuf_MessageOptions_msginit = {
-  &google_protobuf_MessageOptions_submsgs[0],
-  &google_protobuf_MessageOptions__fields[0],
-  UPB_SIZE(12, 16), 5, false,
-};
-
-static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
-  &google_protobuf_UninterpretedOption_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = {
-  {1, UPB_SIZE(8, 8), 1, 0, 14, 1},
-  {2, UPB_SIZE(24, 24), 3, 0, 8, 1},
-  {3, UPB_SIZE(25, 25), 4, 0, 8, 1},
-  {5, UPB_SIZE(26, 26), 5, 0, 8, 1},
-  {6, UPB_SIZE(16, 16), 2, 0, 14, 1},
-  {10, UPB_SIZE(27, 27), 6, 0, 8, 1},
-  {999, UPB_SIZE(28, 32), 0, 0, 11, 3},
-};
-
-const upb_msglayout google_protobuf_FieldOptions_msginit = {
-  &google_protobuf_FieldOptions_submsgs[0],
-  &google_protobuf_FieldOptions__fields[0],
-  UPB_SIZE(32, 40), 7, false,
-};
-
-static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = {
-  &google_protobuf_UninterpretedOption_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = {
-  {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
-};
-
-const upb_msglayout google_protobuf_OneofOptions_msginit = {
-  &google_protobuf_OneofOptions_submsgs[0],
-  &google_protobuf_OneofOptions__fields[0],
-  UPB_SIZE(4, 8), 1, false,
-};
-
-static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = {
-  &google_protobuf_UninterpretedOption_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = {
-  {2, UPB_SIZE(1, 1), 1, 0, 8, 1},
-  {3, UPB_SIZE(2, 2), 2, 0, 8, 1},
-  {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
-};
-
-const upb_msglayout google_protobuf_EnumOptions_msginit = {
-  &google_protobuf_EnumOptions_submsgs[0],
-  &google_protobuf_EnumOptions__fields[0],
-  UPB_SIZE(8, 16), 3, false,
-};
-
-static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = {
-  &google_protobuf_UninterpretedOption_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = {
-  {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
-  {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
-};
-
-const upb_msglayout google_protobuf_EnumValueOptions_msginit = {
-  &google_protobuf_EnumValueOptions_submsgs[0],
-  &google_protobuf_EnumValueOptions__fields[0],
-  UPB_SIZE(8, 16), 2, false,
-};
-
-static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = {
-  &google_protobuf_UninterpretedOption_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = {
-  {33, UPB_SIZE(1, 1), 1, 0, 8, 1},
-  {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
-};
-
-const upb_msglayout google_protobuf_ServiceOptions_msginit = {
-  &google_protobuf_ServiceOptions_submsgs[0],
-  &google_protobuf_ServiceOptions__fields[0],
-  UPB_SIZE(8, 16), 2, false,
-};
-
-static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
-  &google_protobuf_UninterpretedOption_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = {
-  {33, UPB_SIZE(16, 16), 2, 0, 8, 1},
-  {34, UPB_SIZE(8, 8), 1, 0, 14, 1},
-  {999, UPB_SIZE(20, 24), 0, 0, 11, 3},
-};
-
-const upb_msglayout google_protobuf_MethodOptions_msginit = {
-  &google_protobuf_MethodOptions_submsgs[0],
-  &google_protobuf_MethodOptions__fields[0],
-  UPB_SIZE(24, 32), 3, false,
-};
-
-static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = {
-  &google_protobuf_UninterpretedOption_NamePart_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = {
-  {2, UPB_SIZE(56, 80), 0, 0, 11, 3},
-  {3, UPB_SIZE(32, 32), 4, 0, 9, 1},
-  {4, UPB_SIZE(8, 8), 1, 0, 4, 1},
-  {5, UPB_SIZE(16, 16), 2, 0, 3, 1},
-  {6, UPB_SIZE(24, 24), 3, 0, 1, 1},
-  {7, UPB_SIZE(40, 48), 5, 0, 12, 1},
-  {8, UPB_SIZE(48, 64), 6, 0, 9, 1},
-};
-
-const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
-  &google_protobuf_UninterpretedOption_submsgs[0],
-  &google_protobuf_UninterpretedOption__fields[0],
-  UPB_SIZE(64, 96), 7, false,
-};
-
-static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
-  {1, UPB_SIZE(8, 16), 2, 0, 9, 2},
-  {2, UPB_SIZE(1, 1), 1, 0, 8, 2},
-};
-
-const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = {
-  NULL,
-  &google_protobuf_UninterpretedOption_NamePart__fields[0],
-  UPB_SIZE(16, 32), 2, false,
-};
-
-static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = {
-  &google_protobuf_SourceCodeInfo_Location_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
-};
-
-const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
-  &google_protobuf_SourceCodeInfo_submsgs[0],
-  &google_protobuf_SourceCodeInfo__fields[0],
-  UPB_SIZE(4, 8), 1, false,
-};
-
-static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = {
-  {1, UPB_SIZE(24, 48), 0, 0, 5, 3},
-  {2, UPB_SIZE(28, 56), 0, 0, 5, 3},
-  {3, UPB_SIZE(8, 16), 1, 0, 9, 1},
-  {4, UPB_SIZE(16, 32), 2, 0, 9, 1},
-  {6, UPB_SIZE(32, 64), 0, 0, 9, 3},
-};
-
-const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = {
-  NULL,
-  &google_protobuf_SourceCodeInfo_Location__fields[0],
-  UPB_SIZE(40, 80), 5, false,
-};
-
-static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = {
-  &google_protobuf_GeneratedCodeInfo_Annotation_msginit,
-};
-
-static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
-};
-
-const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
-  &google_protobuf_GeneratedCodeInfo_submsgs[0],
-  &google_protobuf_GeneratedCodeInfo__fields[0],
-  UPB_SIZE(4, 8), 1, false,
-};
-
-static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
-  {1, UPB_SIZE(24, 32), 0, 0, 5, 3},
-  {2, UPB_SIZE(16, 16), 3, 0, 9, 1},
-  {3, UPB_SIZE(4, 4), 1, 0, 5, 1},
-  {4, UPB_SIZE(8, 8), 2, 0, 5, 1},
-};
-
-const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
-  NULL,
-  &google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
-  UPB_SIZE(32, 48), 4, false,
-};
-
-
-
 
 /* Maps descriptor type -> upb field type.  */
-const uint8_t upb_desctype_to_fieldtype[] = {
+static const uint8_t upb_desctype_to_fieldtype[] = {
   UPB_WIRE_TYPE_END_GROUP,  /* ENDGROUP */
   UPB_TYPE_DOUBLE,          /* DOUBLE */
   UPB_TYPE_FLOAT,           /* FLOAT */
@@ -524,6 +27,7 @@
 
 /* Data pertaining to the parse. */
 typedef struct {
+  upb_env *env;
   /* Current decoding pointer.  Points to the beginning of a field until we
    * have finished decoding the whole field. */
   const char *ptr;
@@ -536,7 +40,7 @@
 
   /* These members are unset for an unknown group frame. */
   char *msg;
-  const upb_msglayout *m;
+  const upb_msglayout_msginit_v1 *m;
 } upb_decframe;
 
 #define CHK(x) if (!(x)) { return false; }
@@ -545,7 +49,7 @@
                                   const char *limit);
 static bool upb_decode_message(upb_decstate *d, const char *limit,
                                int group_number, char *msg,
-                               const upb_msglayout *l);
+                               const upb_msglayout_msginit_v1 *l);
 
 static bool upb_decode_varint(const char **ptr, const char *limit,
                               uint64_t *val) {
@@ -626,7 +130,9 @@
 
 static bool upb_append_unknown(upb_decstate *d, upb_decframe *frame,
                                const char *start) {
-  upb_msg_addunknown(frame->msg, start, d->ptr - start);
+  UPB_UNUSED(d);
+  UPB_UNUSED(frame);
+  UPB_UNUSED(start);
   return true;
 }
 
@@ -665,7 +171,6 @@
   size_t new_bytes;
   size_t old_bytes;
   void *new_data;
-  upb_alloc *alloc = upb_arena_alloc(arr->arena);
 
   while (new_size < needed) {
     new_size *= 2;
@@ -673,7 +178,7 @@
 
   old_bytes = arr->len * arr->element_size;
   new_bytes = new_size * arr->element_size;
-  new_data = upb_realloc(alloc, arr->data, old_bytes, new_bytes);
+  new_data = upb_realloc(arr->alloc, arr->data, old_bytes, new_bytes);
   CHK(new_data);
 
   arr->data = new_data;
@@ -695,21 +200,23 @@
 }
 
 static upb_array *upb_getarr(upb_decframe *frame,
-                             const upb_msglayout_field *field) {
+                             const upb_msglayout_fieldinit_v1 *field) {
   UPB_ASSERT(field->label == UPB_LABEL_REPEATED);
   return *(upb_array**)&frame->msg[field->offset];
 }
 
-static upb_array *upb_getorcreatearr(upb_decframe *frame,
-                                     const upb_msglayout_field *field) {
+static upb_array *upb_getorcreatearr(upb_decstate *d,
+                                     upb_decframe *frame,
+                                     const upb_msglayout_fieldinit_v1 *field) {
   upb_array *arr = upb_getarr(frame, field);
 
   if (!arr) {
-    upb_fieldtype_t type = upb_desctype_to_fieldtype[field->descriptortype];
-    arr = upb_array_new(type, upb_msg_arena(frame->msg));
+    arr = upb_env_malloc(d->env, sizeof(*arr));
     if (!arr) {
       return NULL;
     }
+    upb_array_init(arr, upb_desctype_to_fieldtype[field->type],
+                   upb_arena_alloc(upb_env_arena(d->env)));
     *(upb_array**)&frame->msg[field->offset] = arr;
   }
 
@@ -717,25 +224,26 @@
 }
 
 static void upb_sethasbit(upb_decframe *frame,
-                          const upb_msglayout_field *field) {
-  int32_t hasbit = field->presence;
-  UPB_ASSERT(field->presence > 0);
-  frame->msg[hasbit / 8] |= (1 << (hasbit % 8));
+                          const upb_msglayout_fieldinit_v1 *field) {
+  UPB_ASSERT(field->hasbit != UPB_NO_HASBIT);
+  frame->msg[field->hasbit / 8] |= (1 << (field->hasbit % 8));
 }
 
 static void upb_setoneofcase(upb_decframe *frame,
-                             const upb_msglayout_field *field) {
-  UPB_ASSERT(field->presence < 0);
-  upb_set32(frame->msg, ~field->presence, field->number);
+                             const upb_msglayout_fieldinit_v1 *field) {
+  UPB_ASSERT(field->oneof_index != UPB_NOT_IN_ONEOF);
+  upb_set32(frame->msg, frame->m->oneofs[field->oneof_index].case_offset,
+            field->number);
 }
 
-static char *upb_decode_prepareslot(upb_decframe *frame,
-                                    const upb_msglayout_field *field) {
+static char *upb_decode_prepareslot(upb_decstate *d,
+                                    upb_decframe *frame,
+                                    const upb_msglayout_fieldinit_v1 *field) {
   char *field_mem = frame->msg + field->offset;
   upb_array *arr;
 
   if (field->label == UPB_LABEL_REPEATED) {
-    arr = upb_getorcreatearr(frame, field);
+    arr = upb_getorcreatearr(d, frame, field);
     field_mem = upb_array_reserve(arr, 1);
   }
 
@@ -743,33 +251,36 @@
 }
 
 static void upb_decode_setpresent(upb_decframe *frame,
-                                  const upb_msglayout_field *field) {
+                                  const upb_msglayout_fieldinit_v1 *field) {
   if (field->label == UPB_LABEL_REPEATED) {
    upb_array *arr = upb_getarr(frame, field);
    UPB_ASSERT(arr->len < arr->size);
    arr->len++;
-  } else if (field->presence < 0) {
+  } else if (field->oneof_index != UPB_NOT_IN_ONEOF) {
     upb_setoneofcase(frame, field);
-  } else if (field->presence > 0) {
+  } else if (field->hasbit != UPB_NO_HASBIT) {
     upb_sethasbit(frame, field);
   }
 }
 
-static bool upb_decode_submsg(upb_decstate *d, upb_decframe *frame,
+static bool upb_decode_submsg(upb_decstate *d,
+                              upb_decframe *frame,
                               const char *limit,
-                              const upb_msglayout_field *field,
+                              const upb_msglayout_fieldinit_v1 *field,
                               int group_number) {
-  char *submsg_slot = upb_decode_prepareslot(frame, field);
-  char *submsg = *(void **)submsg_slot;
-  const upb_msglayout *subm;
+  char *submsg = *(void**)&frame->msg[field->offset];
+  const upb_msglayout_msginit_v1 *subm;
 
+  UPB_ASSERT(field->submsg_index != UPB_NO_SUBMSG);
   subm = frame->m->submsgs[field->submsg_index];
   UPB_ASSERT(subm);
 
   if (!submsg) {
-    submsg = upb_msg_new(subm, upb_msg_arena(frame->msg));
+    submsg = upb_env_malloc(d->env, upb_msg_sizeof((upb_msglayout *)subm));
     CHK(submsg);
-    *(void**)submsg_slot = submsg;
+    submsg = upb_msg_init(
+        submsg, (upb_msglayout*)subm, upb_arena_alloc(upb_env_arena(d->env)));
+    *(void**)&frame->msg[field->offset] = submsg;
   }
 
   upb_decode_message(d, limit, group_number, submsg, subm);
@@ -779,15 +290,15 @@
 
 static bool upb_decode_varintfield(upb_decstate *d, upb_decframe *frame,
                                    const char *field_start,
-                                   const upb_msglayout_field *field) {
+                                   const upb_msglayout_fieldinit_v1 *field) {
   uint64_t val;
   void *field_mem;
 
-  field_mem = upb_decode_prepareslot(frame, field);
+  field_mem = upb_decode_prepareslot(d, frame, field);
   CHK(field_mem);
   CHK(upb_decode_varint(&d->ptr, frame->limit, &val));
 
-  switch ((upb_descriptortype_t)field->descriptortype) {
+  switch ((upb_descriptortype_t)field->type) {
     case UPB_DESCRIPTOR_TYPE_INT64:
     case UPB_DESCRIPTOR_TYPE_UINT64:
       memcpy(field_mem, &val, sizeof(val));
@@ -824,15 +335,15 @@
 
 static bool upb_decode_64bitfield(upb_decstate *d, upb_decframe *frame,
                                   const char *field_start,
-                                  const upb_msglayout_field *field) {
+                                  const upb_msglayout_fieldinit_v1 *field) {
   void *field_mem;
   uint64_t val;
 
-  field_mem = upb_decode_prepareslot(frame, field);
+  field_mem = upb_decode_prepareslot(d, frame, field);
   CHK(field_mem);
   CHK(upb_decode_64bit(&d->ptr, frame->limit, &val));
 
-  switch ((upb_descriptortype_t)field->descriptortype) {
+  switch ((upb_descriptortype_t)field->type) {
     case UPB_DESCRIPTOR_TYPE_DOUBLE:
     case UPB_DESCRIPTOR_TYPE_FIXED64:
     case UPB_DESCRIPTOR_TYPE_SFIXED64:
@@ -848,15 +359,15 @@
 
 static bool upb_decode_32bitfield(upb_decstate *d, upb_decframe *frame,
                                   const char *field_start,
-                                  const upb_msglayout_field *field) {
+                                  const upb_msglayout_fieldinit_v1 *field) {
   void *field_mem;
   uint32_t val;
 
-  field_mem = upb_decode_prepareslot(frame, field);
+  field_mem = upb_decode_prepareslot(d, frame, field);
   CHK(field_mem);
   CHK(upb_decode_32bit(&d->ptr, frame->limit, &val));
 
-  switch ((upb_descriptortype_t)field->descriptortype) {
+  switch ((upb_descriptortype_t)field->type) {
     case UPB_DESCRIPTOR_TYPE_FLOAT:
     case UPB_DESCRIPTOR_TYPE_FIXED32:
     case UPB_DESCRIPTOR_TYPE_SFIXED32:
@@ -884,9 +395,9 @@
 
 static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame,
                                const char *field_start,
-                               const upb_msglayout_field *field,
+                               const upb_msglayout_fieldinit_v1 *field,
                                upb_stringview val) {
-  upb_array *arr = upb_getorcreatearr(frame, field);
+  upb_array *arr = upb_getorcreatearr(d, frame, field);
 
 #define VARINT_CASE(ctype, decode) { \
   const char *ptr = val.data; \
@@ -904,7 +415,7 @@
   return true; \
 }
 
-  switch ((upb_descriptortype_t)field->descriptortype) {
+  switch ((upb_descriptortype_t)field->type) {
     case UPB_DESCRIPTOR_TYPE_STRING:
     case UPB_DESCRIPTOR_TYPE_BYTES: {
       void *field_mem = upb_array_add(arr, 1);
@@ -934,28 +445,9 @@
       VARINT_CASE(int32_t, upb_zzdecode_32);
     case UPB_DESCRIPTOR_TYPE_SINT64:
       VARINT_CASE(int64_t, upb_zzdecode_64);
-    case UPB_DESCRIPTOR_TYPE_MESSAGE: {
-      const upb_msglayout *subm;
-      char *submsg;
-      void *field_mem;
-
+    case UPB_DESCRIPTOR_TYPE_MESSAGE:
       CHK(val.size <= (size_t)(frame->limit - val.data));
-      d->ptr -= val.size;
-
-      /* Create elemente message. */
-      subm = frame->m->submsgs[field->submsg_index];
-      UPB_ASSERT(subm);
-
-      submsg = upb_msg_new(subm, upb_msg_arena(frame->msg));
-      CHK(submsg);
-
-      field_mem = upb_array_add(arr, 1);
-      CHK(field_mem);
-      *(void**)field_mem = submsg;
-
-      return upb_decode_message(
-          d, val.data + val.size, frame->group_number, submsg, subm);
-    }
+      return upb_decode_submsg(d, frame, val.data + val.size, field, 0);
     case UPB_DESCRIPTOR_TYPE_GROUP:
       return upb_append_unknown(d, frame, field_start);
   }
@@ -965,7 +457,7 @@
 
 static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame,
                                       const char *field_start,
-                                      const upb_msglayout_field *field) {
+                                      const upb_msglayout_fieldinit_v1 *field) {
   upb_stringview val;
 
   CHK(upb_decode_string(&d->ptr, frame->limit, &val));
@@ -973,17 +465,16 @@
   if (field->label == UPB_LABEL_REPEATED) {
     return upb_decode_toarray(d, frame, field_start, field, val);
   } else {
-    switch ((upb_descriptortype_t)field->descriptortype) {
+    switch ((upb_descriptortype_t)field->type) {
       case UPB_DESCRIPTOR_TYPE_STRING:
       case UPB_DESCRIPTOR_TYPE_BYTES: {
-        void *field_mem = upb_decode_prepareslot(frame, field);
+        void *field_mem = upb_decode_prepareslot(d, frame, field);
         CHK(field_mem);
         memcpy(field_mem, &val, sizeof(val));
         break;
       }
       case UPB_DESCRIPTOR_TYPE_MESSAGE:
         CHK(val.size <= (size_t)(frame->limit - val.data));
-        d->ptr -= val.size;
         CHK(upb_decode_submsg(d, frame, val.data + val.size, field, 0));
         break;
       default:
@@ -995,8 +486,8 @@
   }
 }
 
-static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
-                                                 uint32_t field_number) {
+static const upb_msglayout_fieldinit_v1 *upb_find_field(
+    const upb_msglayout_msginit_v1 *l, uint32_t field_number) {
   /* Lots of optimization opportunities here. */
   int i;
   for (i = 0; i < l->field_count; i++) {
@@ -1012,7 +503,7 @@
   int field_number;
   int wire_type;
   const char *field_start = d->ptr;
-  const upb_msglayout_field *field;
+  const upb_msglayout_fieldinit_v1 *field;
 
   CHK(upb_decode_tag(&d->ptr, frame->limit, &field_number, &wire_type));
   field = upb_find_field(frame->m, field_number);
@@ -1028,7 +519,7 @@
       case UPB_WIRE_TYPE_DELIMITED:
         return upb_decode_delimitedfield(d, frame, field_start, field);
       case UPB_WIRE_TYPE_START_GROUP:
-        CHK(field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP);
+        CHK(field->type == UPB_DESCRIPTOR_TYPE_GROUP);
         return upb_decode_submsg(d, frame, frame->limit, field, field_number);
       case UPB_WIRE_TYPE_END_GROUP:
         CHK(frame->group_number == field_number)
@@ -1039,9 +530,7 @@
     }
   } else {
     CHK(field_number != 0);
-    CHK(upb_skip_unknownfielddata(d, frame, field_number, wire_type));
-    CHK(upb_append_unknown(d, frame, field_start));
-    return true;
+    return upb_skip_unknownfielddata(d, frame, field_number, wire_type);
   }
 }
 
@@ -1066,7 +555,7 @@
 
 static bool upb_decode_message(upb_decstate *d, const char *limit,
                                int group_number, char *msg,
-                               const upb_msglayout *l) {
+                               const upb_msglayout_msginit_v1 *l) {
   upb_decframe frame;
   frame.group_number = group_number;
   frame.limit = limit;
@@ -1080,9 +569,11 @@
   return true;
 }
 
-bool upb_decode(upb_stringview buf, void *msg, const upb_msglayout *l) {
+bool upb_decode(upb_stringview buf, void *msg,
+                const upb_msglayout_msginit_v1 *l, upb_env *env) {
   upb_decstate state;
   state.ptr = buf.data;
+  state.env = env;
 
   return upb_decode_message(&state, buf.data + buf.size, 0, msg, l);
 }
@@ -1452,45 +943,6 @@
   return true;
 }
 
-static void assign_msg_wellknowntype(upb_msgdef *m) {
-  const char *name = upb_msgdef_fullname(m);
-  if (name == NULL) {
-    m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
-    return;
-  }
-  if (!strcmp(name, "google.protobuf.Duration")) {
-    m->well_known_type = UPB_WELLKNOWN_DURATION;
-  } else if (!strcmp(name, "google.protobuf.Timestamp")) {
-    m->well_known_type = UPB_WELLKNOWN_TIMESTAMP;
-  } else if (!strcmp(name, "google.protobuf.DoubleValue")) {
-    m->well_known_type = UPB_WELLKNOWN_DOUBLEVALUE;
-  } else if (!strcmp(name, "google.protobuf.FloatValue")) {
-    m->well_known_type = UPB_WELLKNOWN_FLOATVALUE;
-  } else if (!strcmp(name, "google.protobuf.Int64Value")) {
-    m->well_known_type = UPB_WELLKNOWN_INT64VALUE;
-  } else if (!strcmp(name, "google.protobuf.UInt64Value")) {
-    m->well_known_type = UPB_WELLKNOWN_UINT64VALUE;
-  } else if (!strcmp(name, "google.protobuf.Int32Value")) {
-    m->well_known_type = UPB_WELLKNOWN_INT32VALUE;
-  } else if (!strcmp(name, "google.protobuf.UInt32Value")) {
-    m->well_known_type = UPB_WELLKNOWN_UINT32VALUE;
-  } else if (!strcmp(name, "google.protobuf.BoolValue")) {
-    m->well_known_type = UPB_WELLKNOWN_BOOLVALUE;
-  } else if (!strcmp(name, "google.protobuf.StringValue")) {
-    m->well_known_type = UPB_WELLKNOWN_STRINGVALUE;
-  } else if (!strcmp(name, "google.protobuf.BytesValue")) {
-    m->well_known_type = UPB_WELLKNOWN_BYTESVALUE;
-  } else if (!strcmp(name, "google.protobuf.Value")) {
-    m->well_known_type = UPB_WELLKNOWN_VALUE;
-  } else if (!strcmp(name, "google.protobuf.ListValue")) {
-    m->well_known_type = UPB_WELLKNOWN_LISTVALUE;
-  } else if (!strcmp(name, "google.protobuf.Struct")) {
-    m->well_known_type = UPB_WELLKNOWN_STRUCT;
-  } else {
-    m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
-  }
-}
-
 bool _upb_def_validate(upb_def *const*defs, size_t n, upb_status *s) {
   size_t i;
 
@@ -1527,8 +979,6 @@
       if (!assign_msg_indices(m, s)) {
         goto err;
       }
-      assign_msg_wellknowntype(m);
-      /* m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; */
     } else if (e) {
       upb_inttable_compact(&e->iton);
     }
@@ -2721,16 +2171,6 @@
   return m->map_entry;
 }
 
-upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m) {
-  return m->well_known_type;
-}
-
-bool upb_msgdef_isnumberwrapper(const upb_msgdef *m) {
-  upb_wellknowntype_t type = upb_msgdef_wellknowntype(m);
-  return type >= UPB_WELLKNOWN_DOUBLEVALUE &&
-         type <= UPB_WELLKNOWN_UINT32VALUE;
-}
-
 void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) {
   upb_inttable_begin(iter, &m->itof);
 }
@@ -3545,7 +2985,7 @@
 static uint64_t upb_zzencode_64(int64_t n) { return (n << 1) ^ (n >> 63); }
 
 typedef struct {
-  upb_alloc *alloc;
+  upb_env *env;
   char *buf, *ptr, *limit;
 } upb_encstate;
 
@@ -3560,11 +3000,11 @@
 static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes) {
   size_t old_size = e->limit - e->buf;
   size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr));
-  char *new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size);
+  char *new_buf = upb_env_realloc(e->env, e->buf, old_size, new_size);
   CHK(new_buf);
 
   /* We want previous data at the end, realloc() put it at the beginning. */
-  memmove(new_buf + new_size - old_size, e->buf, old_size);
+  memmove(e->limit - old_size, e->buf, old_size);
 
   e->ptr = new_buf + new_size - (e->limit - e->ptr);
   e->limit = new_buf + new_size;
@@ -3624,17 +3064,17 @@
   return upb_put_fixed32(e, u32);
 }
 
-static uint32_t upb_readcase(const char *msg, const upb_msglayout_field *f) {
+static uint32_t upb_readcase(const char *msg, const upb_msglayout_msginit_v1 *m,
+                             int oneof_index) {
   uint32_t ret;
-  uint32_t offset = ~f->presence;
-  memcpy(&ret, msg + offset, sizeof(ret));
+  memcpy(&ret, msg + m->oneofs[oneof_index].case_offset, sizeof(ret));
   return ret;
 }
 
-static bool upb_readhasbit(const char *msg, const upb_msglayout_field *f) {
-  uint32_t hasbit = f->presence;
-  UPB_ASSERT(f->presence > 0);
-  return msg[hasbit / 8] & (1 << (hasbit % 8));
+static bool upb_readhasbit(const char *msg,
+                           const upb_msglayout_fieldinit_v1 *f) {
+  UPB_ASSERT(f->hasbit != UPB_NO_HASBIT);
+  return msg[f->hasbit / 8] & (1 << (f->hasbit % 8));
 }
 
 static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) {
@@ -3648,18 +3088,19 @@
 }
 
 bool upb_encode_message(upb_encstate *e, const char *msg,
-                        const upb_msglayout *m, size_t *size);
+                        const upb_msglayout_msginit_v1 *m,
+                        size_t *size);
 
 static bool upb_encode_array(upb_encstate *e, const char *field_mem,
-                             const upb_msglayout *m,
-                             const upb_msglayout_field *f) {
+                             const upb_msglayout_msginit_v1 *m,
+                             const upb_msglayout_fieldinit_v1 *f) {
   const upb_array *arr = *(const upb_array**)field_mem;
 
   if (arr == NULL || arr->len == 0) {
     return true;
   }
 
-  UPB_ASSERT(arr->type == upb_desctype_to_fieldtype2[f->descriptortype]);
+  UPB_ASSERT(arr->type == upb_desctype_to_fieldtype2[f->type]);
 
 #define VARINT_CASE(ctype, encode) { \
   ctype *start = arr->data; \
@@ -3674,7 +3115,7 @@
 break; \
 do { ; } while(0)
 
-  switch (f->descriptortype) {
+  switch (f->type) {
     case UPB_DESCRIPTOR_TYPE_DOUBLE:
       CHK(upb_put_fixedarray(e, arr, sizeof(double)));
       break;
@@ -3693,10 +3134,9 @@
     case UPB_DESCRIPTOR_TYPE_UINT64:
       VARINT_CASE(uint64_t, *ptr);
     case UPB_DESCRIPTOR_TYPE_UINT32:
-      VARINT_CASE(uint32_t, *ptr);
     case UPB_DESCRIPTOR_TYPE_INT32:
     case UPB_DESCRIPTOR_TYPE_ENUM:
-      VARINT_CASE(int32_t, (int64_t)*ptr);
+      VARINT_CASE(uint32_t, *ptr);
     case UPB_DESCRIPTOR_TYPE_BOOL:
       VARINT_CASE(bool, *ptr);
     case UPB_DESCRIPTOR_TYPE_SINT32:
@@ -3718,7 +3158,7 @@
     case UPB_DESCRIPTOR_TYPE_GROUP: {
       void **start = arr->data;
       void **ptr = start + arr->len;
-      const upb_msglayout *subm = m->submsgs[f->submsg_index];
+      const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
       do {
         size_t size;
         ptr--;
@@ -3731,7 +3171,7 @@
     case UPB_DESCRIPTOR_TYPE_MESSAGE: {
       void **start = arr->data;
       void **ptr = start + arr->len;
-      const upb_msglayout *subm = m->submsgs[f->submsg_index];
+      const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
       do {
         size_t size;
         ptr--;
@@ -3751,9 +3191,11 @@
 }
 
 static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem,
-                                   const upb_msglayout *m,
-                                   const upb_msglayout_field *f,
-                                   bool skip_zero_value) {
+                                   const upb_msglayout_msginit_v1 *m,
+                                   const upb_msglayout_fieldinit_v1 *f,
+                                   bool is_proto3) {
+  bool skip_zero_value = is_proto3 && f->oneof_index == UPB_NOT_IN_ONEOF;
+
 #define CASE(ctype, type, wire_type, encodeval) do { \
   ctype val = *(ctype*)field_mem; \
   if (skip_zero_value && val == 0) { \
@@ -3763,7 +3205,7 @@
       upb_put_tag(e, f->number, wire_type); \
 } while(0)
 
-  switch (f->descriptortype) {
+  switch (f->type) {
     case UPB_DESCRIPTOR_TYPE_DOUBLE:
       CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
     case UPB_DESCRIPTOR_TYPE_FLOAT:
@@ -3772,10 +3214,9 @@
     case UPB_DESCRIPTOR_TYPE_UINT64:
       CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
     case UPB_DESCRIPTOR_TYPE_UINT32:
-      CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
     case UPB_DESCRIPTOR_TYPE_INT32:
     case UPB_DESCRIPTOR_TYPE_ENUM:
-      CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val);
+      CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
     case UPB_DESCRIPTOR_TYPE_SFIXED64:
     case UPB_DESCRIPTOR_TYPE_FIXED64:
       CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
@@ -3800,9 +3241,9 @@
     }
     case UPB_DESCRIPTOR_TYPE_GROUP: {
       size_t size;
-      void *submsg = *(void **)field_mem;
-      const upb_msglayout *subm = m->submsgs[f->submsg_index];
-      if (submsg == NULL) {
+      void *submsg = *(void**)field_mem;
+      const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
+      if (skip_zero_value && submsg == NULL) {
         return true;
       }
       return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
@@ -3811,9 +3252,9 @@
     }
     case UPB_DESCRIPTOR_TYPE_MESSAGE: {
       size_t size;
-      void *submsg = *(void **)field_mem;
-      const upb_msglayout *subm = m->submsgs[f->submsg_index];
-      if (submsg == NULL) {
+      void *submsg = *(void**)field_mem;
+      const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
+      if (skip_zero_value && submsg == NULL) {
         return true;
       }
       return upb_encode_message(e, submsg, subm, &size) &&
@@ -3825,52 +3266,49 @@
   UPB_UNREACHABLE();
 }
 
-bool upb_encode_message(upb_encstate *e, const char *msg,
-                        const upb_msglayout *m, size_t *size) {
+bool upb_encode_hasscalarfield(const char *msg,
+                               const upb_msglayout_msginit_v1 *m,
+                               const upb_msglayout_fieldinit_v1 *f) {
+  if (f->oneof_index != UPB_NOT_IN_ONEOF) {
+    return upb_readcase(msg, m, f->oneof_index) == f->number;
+  } else if (m->is_proto2) {
+    return upb_readhasbit(msg, f);
+  } else {
+    /* For proto3, we'll test for the field being empty later. */
+    return true;
+  }
+}
+
+bool upb_encode_message(upb_encstate* e, const char *msg,
+                        const upb_msglayout_msginit_v1 *m,
+                        size_t *size) {
   int i;
-  size_t pre_len = e->limit - e->ptr;
-  const char *unknown;
-  size_t unknown_size;
+  char *buf_end = e->ptr;
+
+  if (msg == NULL) {
+    return true;
+  }
 
   for (i = m->field_count - 1; i >= 0; i--) {
-    const upb_msglayout_field *f = &m->fields[i];
+    const upb_msglayout_fieldinit_v1 *f = &m->fields[i];
 
     if (f->label == UPB_LABEL_REPEATED) {
       CHK(upb_encode_array(e, msg + f->offset, m, f));
     } else {
-      bool skip_empty = false;
-      if (f->presence == 0) {
-        /* Proto3 presence. */
-        skip_empty = true;
-      } else if (f->presence > 0) {
-        /* Proto2 presence: hasbit. */
-        if (!upb_readhasbit(msg, f)) {
-          continue;
-        }
-      } else {
-        /* Field is in a oneof. */
-        if (upb_readcase(msg, f) != f->number) {
-          continue;
-        }
+      if (upb_encode_hasscalarfield(msg, m, f)) {
+        CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, !m->is_proto2));
       }
-      CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, skip_empty));
     }
   }
 
-  unknown = upb_msg_getunknown(msg, &unknown_size);
-
-  if (unknown) {
-    upb_put_bytes(e, unknown, unknown_size);
-  }
-
-  *size = (e->limit - e->ptr) - pre_len;
+  *size = buf_end - e->ptr;
   return true;
 }
 
-char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena,
-                 size_t *size) {
+char *upb_encode(const void *msg, const upb_msglayout_msginit_v1 *m,
+                 upb_env *env, size_t *size) {
   upb_encstate e;
-  e.alloc = upb_arena_alloc(arena);
+  e.env = env;
   e.buf = NULL;
   e.limit = NULL;
   e.ptr = NULL;
@@ -4595,6 +4033,1095 @@
 }
 
 
+static bool is_power_of_two(size_t val) {
+  return (val & (val - 1)) == 0;
+}
+
+/* Align up to the given power of 2. */
+static size_t align_up(size_t val, size_t align) {
+  UPB_ASSERT(is_power_of_two(align));
+  return (val + align - 1) & ~(align - 1);
+}
+
+static size_t div_round_up(size_t n, size_t d) {
+  return (n + d - 1) / d;
+}
+
+bool upb_fieldtype_mapkeyok(upb_fieldtype_t type) {
+  return type == UPB_TYPE_BOOL || type == UPB_TYPE_INT32 ||
+         type == UPB_TYPE_UINT32 || type == UPB_TYPE_INT64 ||
+         type == UPB_TYPE_UINT64 || type == UPB_TYPE_STRING;
+}
+
+void *upb_array_pack(const upb_array *arr, void *p, size_t *ofs, size_t size);
+void *upb_map_pack(const upb_map *map, void *p, size_t *ofs, size_t size);
+
+#define PTR_AT(msg, ofs, type) (type*)((char*)msg + ofs)
+#define VOIDPTR_AT(msg, ofs) PTR_AT(msg, ofs, void)
+#define ENCODE_MAX_NESTING 64
+#define CHECK_TRUE(x) if (!(x)) { return false; }
+
+/** upb_msgval ****************************************************************/
+
+#define upb_alignof(t) offsetof(struct { char c; t x; }, x)
+
+/* These functions will generate real memcpy() calls on ARM sadly, because
+ * the compiler assumes they might not be aligned. */
+
+static upb_msgval upb_msgval_read(const void *p, size_t ofs,
+                                  uint8_t size) {
+  upb_msgval val;
+  p = (char*)p + ofs;
+  memcpy(&val, p, size);
+  return val;
+}
+
+static void upb_msgval_write(void *p, size_t ofs, upb_msgval val,
+                             uint8_t size) {
+  p = (char*)p + ofs;
+  memcpy(p, &val, size);
+}
+
+static size_t upb_msgval_sizeof(upb_fieldtype_t type) {
+  switch (type) {
+    case UPB_TYPE_DOUBLE:
+    case UPB_TYPE_INT64:
+    case UPB_TYPE_UINT64:
+      return 8;
+    case UPB_TYPE_ENUM:
+    case UPB_TYPE_INT32:
+    case UPB_TYPE_UINT32:
+    case UPB_TYPE_FLOAT:
+      return 4;
+    case UPB_TYPE_BOOL:
+      return 1;
+    case UPB_TYPE_BYTES:
+    case UPB_TYPE_MESSAGE:
+      return sizeof(void*);
+    case UPB_TYPE_STRING:
+      return sizeof(upb_stringview);
+  }
+  UPB_UNREACHABLE();
+}
+
+static uint8_t upb_msg_fieldsize(const upb_msglayout_fieldinit_v1 *field) {
+  if (field->label == UPB_LABEL_REPEATED) {
+    return sizeof(void*);
+  } else {
+    return upb_msgval_sizeof(field->type);
+  }
+}
+
+static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
+  if (upb_fielddef_isseq(f)) {
+    return sizeof(void*);
+  } else {
+    return upb_msgval_sizeof(upb_fielddef_type(f));
+  }
+}
+
+/* TODO(haberman): this is broken right now because upb_msgval can contain
+ * a char* / size_t pair, which is too big for a upb_value.  To fix this
+ * we'll probably need to dynamically allocate a upb_msgval and store a
+ * pointer to that in the tables for extensions/maps. */
+static upb_value upb_toval(upb_msgval val) {
+  upb_value ret;
+  UPB_UNUSED(val);
+  memset(&ret, 0, sizeof(upb_value));  /* XXX */
+  return ret;
+}
+
+static upb_msgval upb_msgval_fromval(upb_value val) {
+  upb_msgval ret;
+  UPB_UNUSED(val);
+  memset(&ret, 0, sizeof(upb_msgval));  /* XXX */
+  return ret;
+}
+
+static upb_ctype_t upb_fieldtotabtype(upb_fieldtype_t type) {
+  switch (type) {
+    case UPB_TYPE_FLOAT: return UPB_CTYPE_FLOAT;
+    case UPB_TYPE_DOUBLE: return UPB_CTYPE_DOUBLE;
+    case UPB_TYPE_BOOL: return UPB_CTYPE_BOOL;
+    case UPB_TYPE_BYTES:
+    case UPB_TYPE_MESSAGE:
+    case UPB_TYPE_STRING: return UPB_CTYPE_CONSTPTR;
+    case UPB_TYPE_ENUM:
+    case UPB_TYPE_INT32: return UPB_CTYPE_INT32;
+    case UPB_TYPE_UINT32: return UPB_CTYPE_UINT32;
+    case UPB_TYPE_INT64: return UPB_CTYPE_INT64;
+    case UPB_TYPE_UINT64: return UPB_CTYPE_UINT64;
+    default: UPB_ASSERT(false); return 0;
+  }
+}
+
+static upb_msgval upb_msgval_fromdefault(const upb_fielddef *f) {
+  switch (upb_fielddef_type(f)) {
+      case UPB_TYPE_FLOAT:
+        return upb_msgval_float(upb_fielddef_defaultfloat(f));
+      case UPB_TYPE_DOUBLE:
+        return upb_msgval_double(upb_fielddef_defaultdouble(f));
+      case UPB_TYPE_BOOL:
+        return upb_msgval_bool(upb_fielddef_defaultbool(f));
+      case UPB_TYPE_STRING:
+      case UPB_TYPE_BYTES: {
+        size_t len;
+        const char *ptr = upb_fielddef_defaultstr(f, &len);
+        return upb_msgval_makestr(ptr, len);
+      }
+      case UPB_TYPE_MESSAGE:
+        return upb_msgval_msg(NULL);
+      case UPB_TYPE_ENUM:
+      case UPB_TYPE_INT32:
+        return upb_msgval_int32(upb_fielddef_defaultint32(f));
+      case UPB_TYPE_UINT32:
+        return upb_msgval_uint32(upb_fielddef_defaultuint32(f));
+      case UPB_TYPE_INT64:
+        return upb_msgval_int64(upb_fielddef_defaultint64(f));
+      case UPB_TYPE_UINT64:
+        return upb_msgval_uint64(upb_fielddef_defaultuint64(f));
+      default:
+        UPB_ASSERT(false);
+        return upb_msgval_msg(NULL);
+  }
+}
+
+
+/** upb_msglayout *************************************************************/
+
+struct upb_msglayout {
+  struct upb_msglayout_msginit_v1 data;
+};
+
+static void upb_msglayout_free(upb_msglayout *l) {
+  upb_gfree(l->data.default_msg);
+  upb_gfree(l);
+}
+
+static size_t upb_msglayout_place(upb_msglayout *l, size_t size) {
+  size_t ret;
+
+  l->data.size = align_up(l->data.size, size);
+  ret = l->data.size;
+  l->data.size += size;
+  return ret;
+}
+
+static uint32_t upb_msglayout_offset(const upb_msglayout *l,
+                                     const upb_fielddef *f) {
+  return l->data.fields[upb_fielddef_index(f)].offset;
+}
+
+static uint32_t upb_msglayout_hasbit(const upb_msglayout *l,
+                                     const upb_fielddef *f) {
+  return l->data.fields[upb_fielddef_index(f)].hasbit;
+}
+
+static bool upb_msglayout_initdefault(upb_msglayout *l, const upb_msgdef *m) {
+  upb_msg_field_iter it;
+
+  if (upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2 && l->data.size) {
+    /* Allocate default message and set default values in it. */
+    l->data.default_msg = upb_gmalloc(l->data.size);
+    if (!l->data.default_msg) {
+      return false;
+    }
+
+    memset(l->data.default_msg, 0, l->data.size);
+
+    for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
+         upb_msg_field_next(&it)) {
+      const upb_fielddef* f = upb_msg_iter_field(&it);
+
+      if (upb_fielddef_containingoneof(f)) {
+        continue;
+      }
+
+      /* TODO(haberman): handle strings. */
+      if (!upb_fielddef_isstring(f) &&
+          !upb_fielddef_issubmsg(f) &&
+          !upb_fielddef_isseq(f)) {
+        upb_msg_set(l->data.default_msg,
+                    upb_fielddef_index(f),
+                    upb_msgval_fromdefault(f),
+                    l);
+      }
+    }
+  }
+
+  return true;
+}
+
+static upb_msglayout *upb_msglayout_new(const upb_msgdef *m) {
+  upb_msg_field_iter it;
+  upb_msg_oneof_iter oit;
+  upb_msglayout *l;
+  size_t hasbit;
+  size_t submsg_count = 0;
+  const upb_msglayout_msginit_v1 **submsgs;
+  upb_msglayout_fieldinit_v1 *fields;
+  upb_msglayout_oneofinit_v1 *oneofs;
+
+  for (upb_msg_field_begin(&it, m);
+       !upb_msg_field_done(&it);
+       upb_msg_field_next(&it)) {
+    const upb_fielddef* f = upb_msg_iter_field(&it);
+    if (upb_fielddef_issubmsg(f)) {
+      submsg_count++;
+    }
+  }
+
+  l = upb_gmalloc(sizeof(*l));
+  if (!l) return NULL;
+
+  memset(l, 0, sizeof(*l));
+
+  fields = upb_gmalloc(upb_msgdef_numfields(m) * sizeof(*fields));
+  submsgs = upb_gmalloc(submsg_count * sizeof(*submsgs));
+  oneofs = upb_gmalloc(upb_msgdef_numoneofs(m) * sizeof(*oneofs));
+
+  if ((!fields && upb_msgdef_numfields(m)) ||
+      (!submsgs && submsg_count) ||
+      (!oneofs && upb_msgdef_numoneofs(m))) {
+    /* OOM. */
+    upb_gfree(l);
+    upb_gfree(fields);
+    upb_gfree(submsgs);
+    upb_gfree(oneofs);
+    return NULL;
+  }
+
+  l->data.field_count = upb_msgdef_numfields(m);
+  l->data.oneof_count = upb_msgdef_numoneofs(m);
+  l->data.fields = fields;
+  l->data.submsgs = submsgs;
+  l->data.oneofs = oneofs;
+  l->data.is_proto2 = (upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2);
+
+  /* Allocate data offsets in three stages:
+   *
+   * 1. hasbits.
+   * 2. regular fields.
+   * 3. oneof fields.
+   *
+   * OPT: There is a lot of room for optimization here to minimize the size.
+   */
+
+  /* Allocate hasbits and set basic field attributes. */
+  for (upb_msg_field_begin(&it, m), hasbit = 0;
+       !upb_msg_field_done(&it);
+       upb_msg_field_next(&it)) {
+    const upb_fielddef* f = upb_msg_iter_field(&it);
+    upb_msglayout_fieldinit_v1 *field = &fields[upb_fielddef_index(f)];
+
+    field->number = upb_fielddef_number(f);
+    field->type = upb_fielddef_type(f);
+    field->label = upb_fielddef_label(f);
+
+    if (upb_fielddef_containingoneof(f)) {
+      field->oneof_index = upb_oneofdef_index(upb_fielddef_containingoneof(f));
+    } else {
+      field->oneof_index = UPB_NOT_IN_ONEOF;
+    }
+
+    if (upb_fielddef_haspresence(f) && !upb_fielddef_containingoneof(f)) {
+      field->hasbit = hasbit++;
+    }
+  }
+
+  /* Account for space used by hasbits. */
+  l->data.size = div_round_up(hasbit, 8);
+
+  /* Allocate non-oneof fields. */
+  for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
+       upb_msg_field_next(&it)) {
+    const upb_fielddef* f = upb_msg_iter_field(&it);
+    size_t field_size = upb_msg_fielddefsize(f);
+    size_t index = upb_fielddef_index(f);
+
+    if (upb_fielddef_containingoneof(f)) {
+      /* Oneofs are handled separately below. */
+      continue;
+    }
+
+    fields[index].offset = upb_msglayout_place(l, field_size);
+  }
+
+  /* Allocate oneof fields.  Each oneof field consists of a uint32 for the case
+   * and space for the actual data. */
+  for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
+       upb_msg_oneof_next(&oit)) {
+    const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
+    upb_oneof_iter fit;
+
+    size_t case_size = sizeof(uint32_t);  /* Could potentially optimize this. */
+    upb_msglayout_oneofinit_v1 *oneof = &oneofs[upb_oneofdef_index(o)];
+    size_t field_size = 0;
+
+    /* Calculate field size: the max of all field sizes. */
+    for (upb_oneof_begin(&fit, o);
+         !upb_oneof_done(&fit);
+         upb_oneof_next(&fit)) {
+      const upb_fielddef* f = upb_oneof_iter_field(&fit);
+      field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
+    }
+
+    /* Align and allocate case offset. */
+    oneof->case_offset = upb_msglayout_place(l, case_size);
+    oneof->data_offset = upb_msglayout_place(l, field_size);
+  }
+
+  /* Size of the entire structure should be a multiple of its greatest
+   * alignment.  TODO: track overall alignment for real? */
+  l->data.size = align_up(l->data.size, 8);
+
+  if (upb_msglayout_initdefault(l, m)) {
+    return l;
+  } else {
+    upb_msglayout_free(l);
+    return NULL;
+  }
+}
+
+
+/** upb_msgfactory ************************************************************/
+
+struct upb_msgfactory {
+  const upb_symtab *symtab;  /* We own a ref. */
+  upb_inttable layouts;
+  upb_inttable mergehandlers;
+};
+
+upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab) {
+  upb_msgfactory *ret = upb_gmalloc(sizeof(*ret));
+
+  ret->symtab = symtab;
+  upb_inttable_init(&ret->layouts, UPB_CTYPE_PTR);
+  upb_inttable_init(&ret->mergehandlers, UPB_CTYPE_CONSTPTR);
+
+  return ret;
+}
+
+void upb_msgfactory_free(upb_msgfactory *f) {
+  upb_inttable_iter i;
+  upb_inttable_begin(&i, &f->layouts);
+  for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+    upb_msglayout *l = upb_value_getptr(upb_inttable_iter_value(&i));
+    upb_msglayout_free(l);
+  }
+
+  upb_inttable_begin(&i, &f->mergehandlers);
+  for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+    const upb_handlers *h = upb_value_getconstptr(upb_inttable_iter_value(&i));
+    upb_handlers_unref(h, f);
+  }
+
+  upb_inttable_uninit(&f->layouts);
+  upb_inttable_uninit(&f->mergehandlers);
+  upb_gfree(f);
+}
+
+const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f) {
+  return f->symtab;
+}
+
+const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
+                                              const upb_msgdef *m) {
+  upb_value v;
+  UPB_ASSERT(upb_symtab_lookupmsg(f->symtab, upb_msgdef_fullname(m)) == m);
+  UPB_ASSERT(!upb_msgdef_mapentry(m));
+
+  if (upb_inttable_lookupptr(&f->layouts, m, &v)) {
+    UPB_ASSERT(upb_value_getptr(v));
+    return upb_value_getptr(v);
+  } else {
+    upb_msgfactory *mutable_f = (void*)f;
+    upb_msglayout *l = upb_msglayout_new(m);
+    upb_inttable_insertptr(&mutable_f->layouts, m, upb_value_ptr(l));
+    UPB_ASSERT(l);
+    return l;
+  }
+}
+
+/* Our handlers that we don't expose externally. */
+
+void *upb_msg_startstr(void *msg, const void *hd, size_t size_hint) {
+  uint32_t ofs = (uintptr_t)hd;
+  upb_alloc *alloc = upb_msg_alloc(msg);
+  upb_msgval val;
+  UPB_UNUSED(size_hint);
+
+  val = upb_msgval_read(msg, ofs, upb_msgval_sizeof(UPB_TYPE_STRING));
+
+  upb_free(alloc, (void*)val.str.data);
+  val.str.data = NULL;
+  val.str.size = 0;
+
+  upb_msgval_write(msg, ofs, val, upb_msgval_sizeof(UPB_TYPE_STRING));
+  return msg;
+}
+
+size_t upb_msg_str(void *msg, const void *hd, const char *ptr, size_t size,
+                   const upb_bufhandle *handle) {
+  uint32_t ofs = (uintptr_t)hd;
+  upb_alloc *alloc = upb_msg_alloc(msg);
+  upb_msgval val;
+  size_t newsize;
+  UPB_UNUSED(handle);
+
+  val = upb_msgval_read(msg, ofs, upb_msgval_sizeof(UPB_TYPE_STRING));
+
+  newsize = val.str.size + size;
+  val.str.data = upb_realloc(alloc, (void*)val.str.data, val.str.size, newsize);
+
+  if (!val.str.data) {
+    return false;
+  }
+
+  memcpy((char*)val.str.data + val.str.size, ptr, size);
+  val.str.size = newsize;
+  upb_msgval_write(msg, ofs, val, upb_msgval_sizeof(UPB_TYPE_STRING));
+  return size;
+}
+
+static void callback(const void *closure, upb_handlers *h) {
+  upb_msgfactory *factory = (upb_msgfactory*)closure;
+  const upb_msgdef *md = upb_handlers_msgdef(h);
+  const upb_msglayout* layout = upb_msgfactory_getlayout(factory, md);
+  upb_msg_field_iter i;
+  UPB_UNUSED(factory);
+
+  for(upb_msg_field_begin(&i, md);
+      !upb_msg_field_done(&i);
+      upb_msg_field_next(&i)) {
+    const upb_fielddef *f = upb_msg_iter_field(&i);
+    size_t offset = upb_msglayout_offset(layout, f);
+    upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
+    upb_handlerattr_sethandlerdata(&attr, (void*)offset);
+
+    if (upb_fielddef_isseq(f)) {
+    } else if (upb_fielddef_isstring(f)) {
+      upb_handlers_setstartstr(h, f, upb_msg_startstr, &attr);
+      upb_handlers_setstring(h, f, upb_msg_str, &attr);
+    } else {
+      upb_msg_setscalarhandler(
+          h, f, offset, upb_msglayout_hasbit(layout, f));
+    }
+  }
+}
+
+const upb_handlers *upb_msgfactory_getmergehandlers(upb_msgfactory *f,
+                                                    const upb_msgdef *m) {
+  upb_msgfactory *mutable_f = (void*)f;
+
+  /* TODO(haberman): properly cache these. */
+  const upb_handlers *ret = upb_handlers_newfrozen(m, f, callback, f);
+  upb_inttable_push(&mutable_f->mergehandlers, upb_value_constptr(ret));
+
+  return ret;
+}
+
+const upb_visitorplan *upb_msgfactory_getvisitorplan(upb_msgfactory *f,
+                                                     const upb_handlers *h) {
+  const upb_msgdef *md = upb_handlers_msgdef(h);
+  return (const upb_visitorplan*)upb_msgfactory_getlayout(f, md);
+}
+
+
+/** upb_visitor ***************************************************************/
+
+struct upb_visitor {
+  const upb_msglayout *layout;
+  upb_sink *sink;
+};
+
+static upb_selector_t getsel2(const upb_fielddef *f, upb_handlertype_t type) {
+  upb_selector_t ret;
+  bool ok = upb_handlers_getselector(f, type, &ret);
+  UPB_ASSERT(ok);
+  return ret;
+}
+
+static bool upb_visitor_hasfield(const upb_msg *msg, const upb_fielddef *f,
+                                 const upb_msglayout *layout) {
+  int field_index = upb_fielddef_index(f);
+  if (upb_fielddef_isseq(f)) {
+    return upb_msgval_getarr(upb_msg_get(msg, field_index, layout)) != NULL;
+  } else if (upb_msgdef_syntax(upb_fielddef_containingtype(f)) ==
+             UPB_SYNTAX_PROTO2) {
+    return upb_msg_has(msg, field_index, layout);
+  } else {
+    upb_msgval val = upb_msg_get(msg, field_index, layout);
+    switch (upb_fielddef_type(f)) {
+      case UPB_TYPE_FLOAT:
+        return upb_msgval_getfloat(val) != 0;
+      case UPB_TYPE_DOUBLE:
+        return upb_msgval_getdouble(val) != 0;
+      case UPB_TYPE_BOOL:
+        return upb_msgval_getbool(val);
+      case UPB_TYPE_ENUM:
+      case UPB_TYPE_INT32:
+        return upb_msgval_getint32(val) != 0;
+      case UPB_TYPE_UINT32:
+        return upb_msgval_getuint32(val) != 0;
+      case UPB_TYPE_INT64:
+        return upb_msgval_getint64(val) != 0;
+      case UPB_TYPE_UINT64:
+        return upb_msgval_getuint64(val) != 0;
+      case UPB_TYPE_STRING:
+      case UPB_TYPE_BYTES:
+        return upb_msgval_getstr(val).size > 0;
+      case UPB_TYPE_MESSAGE:
+        return upb_msgval_getmsg(val) != NULL;
+    }
+    UPB_UNREACHABLE();
+  }
+}
+
+static bool upb_visitor_visitmsg2(const upb_msg *msg,
+                                  const upb_msglayout *layout, upb_sink *sink,
+                                  int depth) {
+  const upb_msgdef *md = upb_handlers_msgdef(sink->handlers);
+  upb_msg_field_iter i;
+  upb_status status;
+
+  upb_sink_startmsg(sink);
+
+  /* Protect against cycles (possible because users may freely reassign message
+   * and repeated fields) by imposing a maximum recursion depth. */
+  if (depth > ENCODE_MAX_NESTING) {
+    return false;
+  }
+
+  for (upb_msg_field_begin(&i, md);
+       !upb_msg_field_done(&i);
+       upb_msg_field_next(&i)) {
+    upb_fielddef *f = upb_msg_iter_field(&i);
+    upb_msgval val;
+
+    if (!upb_visitor_hasfield(msg, f, layout)) {
+      continue;
+    }
+
+    val = upb_msg_get(msg, upb_fielddef_index(f), layout);
+
+    if (upb_fielddef_isseq(f)) {
+      const upb_array *arr = upb_msgval_getarr(val);
+      UPB_ASSERT(arr);
+      /* TODO: putary(ary, f, sink, depth);*/
+    } else if (upb_fielddef_issubmsg(f)) {
+      const upb_map *map = upb_msgval_getmap(val);
+      UPB_ASSERT(map);
+      /* TODO: putmap(map, f, sink, depth);*/
+    } else if (upb_fielddef_isstring(f)) {
+      /* TODO putstr(); */
+    } else {
+      upb_selector_t sel = getsel2(f, upb_handlers_getprimitivehandlertype(f));
+      UPB_ASSERT(upb_fielddef_isprimitive(f));
+
+      switch (upb_fielddef_type(f)) {
+        case UPB_TYPE_FLOAT:
+          CHECK_TRUE(upb_sink_putfloat(sink, sel, upb_msgval_getfloat(val)));
+          break;
+        case UPB_TYPE_DOUBLE:
+          CHECK_TRUE(upb_sink_putdouble(sink, sel, upb_msgval_getdouble(val)));
+          break;
+        case UPB_TYPE_BOOL:
+          CHECK_TRUE(upb_sink_putbool(sink, sel, upb_msgval_getbool(val)));
+          break;
+        case UPB_TYPE_ENUM:
+        case UPB_TYPE_INT32:
+          CHECK_TRUE(upb_sink_putint32(sink, sel, upb_msgval_getint32(val)));
+          break;
+        case UPB_TYPE_UINT32:
+          CHECK_TRUE(upb_sink_putuint32(sink, sel, upb_msgval_getuint32(val)));
+          break;
+        case UPB_TYPE_INT64:
+          CHECK_TRUE(upb_sink_putint64(sink, sel, upb_msgval_getint64(val)));
+          break;
+        case UPB_TYPE_UINT64:
+          CHECK_TRUE(upb_sink_putuint64(sink, sel, upb_msgval_getuint64(val)));
+          break;
+        case UPB_TYPE_STRING:
+        case UPB_TYPE_BYTES:
+        case UPB_TYPE_MESSAGE:
+          UPB_UNREACHABLE();
+      }
+    }
+  }
+
+  upb_sink_endmsg(sink, &status);
+  return true;
+}
+
+upb_visitor *upb_visitor_create(upb_env *e, const upb_visitorplan *vp,
+                                upb_sink *output) {
+  upb_visitor *visitor = upb_env_malloc(e, sizeof(*visitor));
+  visitor->layout = (const upb_msglayout*)vp;
+  visitor->sink = output;
+  return visitor;
+}
+
+bool upb_visitor_visitmsg(upb_visitor *visitor, const upb_msg *msg) {
+  return upb_visitor_visitmsg2(msg, visitor->layout, visitor->sink, 0);
+}
+
+
+/** upb_msg *******************************************************************/
+
+/* If we always read/write as a consistent type to each address, this shouldn't
+ * violate aliasing.
+ */
+#define DEREF(msg, ofs, type) *PTR_AT(msg, ofs, type)
+
+/* Internal members of a upb_msg.  We can change this without breaking binary
+ * compatibility.  We put these before the user's data.  The user's upb_msg*
+ * points after the upb_msg_internal. */
+
+/* Used when a message is not extendable. */
+typedef struct {
+  /* TODO(haberman): add unknown fields. */
+  upb_alloc *alloc;
+} upb_msg_internal;
+
+/* Used when a message is extendable. */
+typedef struct {
+  upb_inttable *extdict;
+  upb_msg_internal base;
+} upb_msg_internal_withext;
+
+static int upb_msg_internalsize(const upb_msglayout *l) {
+    return sizeof(upb_msg_internal) - l->data.extendable * sizeof(void*);
+}
+
+static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) {
+  return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
+}
+
+static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
+  return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
+}
+
+static upb_msg_internal_withext *upb_msg_getinternalwithext(
+    upb_msg *msg, const upb_msglayout *l) {
+  UPB_ASSERT(l->data.extendable);
+  return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext));
+}
+
+static const upb_msglayout_fieldinit_v1 *upb_msg_checkfield(
+    int field_index, const upb_msglayout *l) {
+  UPB_ASSERT(field_index >= 0 && field_index < l->data.field_count);
+  return &l->data.fields[field_index];
+}
+
+static bool upb_msg_inoneof(const upb_msglayout_fieldinit_v1 *field) {
+  return field->oneof_index != UPB_NOT_IN_ONEOF;
+}
+
+static uint32_t *upb_msg_oneofcase(const upb_msg *msg, int field_index,
+                                   const upb_msglayout *l) {
+  const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
+  UPB_ASSERT(upb_msg_inoneof(field));
+  return PTR_AT(msg, l->data.oneofs[field->oneof_index].case_offset, uint32_t);
+}
+
+size_t upb_msg_sizeof(const upb_msglayout *l) {
+  return l->data.size + upb_msg_internalsize(l);
+}
+
+upb_msg *upb_msg_init(void *mem, const upb_msglayout *l, upb_alloc *a) {
+  upb_msg *msg = VOIDPTR_AT(mem, upb_msg_internalsize(l));
+
+  /* Initialize normal members. */
+  if (l->data.default_msg) {
+    memcpy(msg, l->data.default_msg, l->data.size);
+  } else {
+    memset(msg, 0, l->data.size);
+  }
+
+  /* Initialize internal members. */
+  upb_msg_getinternal(msg)->alloc = a;
+
+  if (l->data.extendable) {
+    upb_msg_getinternalwithext(msg, l)->extdict = NULL;
+  }
+
+  return msg;
+}
+
+void *upb_msg_uninit(upb_msg *msg, const upb_msglayout *l) {
+  if (l->data.extendable) {
+    upb_inttable *ext_dict = upb_msg_getinternalwithext(msg, l)->extdict;
+    if (ext_dict) {
+      upb_inttable_uninit2(ext_dict, upb_msg_alloc(msg));
+      upb_free(upb_msg_alloc(msg), ext_dict);
+    }
+  }
+
+  return VOIDPTR_AT(msg, -upb_msg_internalsize(l));
+}
+
+upb_msg *upb_msg_new(const upb_msglayout *l, upb_alloc *a) {
+  void *mem = upb_malloc(a, upb_msg_sizeof(l));
+  return mem ? upb_msg_init(mem, l, a) : NULL;
+}
+
+void upb_msg_free(upb_msg *msg, const upb_msglayout *l) {
+  upb_free(upb_msg_alloc(msg), upb_msg_uninit(msg, l));
+}
+
+upb_alloc *upb_msg_alloc(const upb_msg *msg) {
+  return upb_msg_getinternal_const(msg)->alloc;
+}
+
+bool upb_msg_has(const upb_msg *msg,
+                 int field_index,
+                 const upb_msglayout *l) {
+  const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
+
+  UPB_ASSERT(l->data.is_proto2);
+
+  if (upb_msg_inoneof(field)) {
+    /* Oneofs are set when the oneof number is set to this field. */
+    return *upb_msg_oneofcase(msg, field_index, l) == field->number;
+  } else {
+    /* Other fields are set when their hasbit is set. */
+    uint32_t hasbit = l->data.fields[field_index].hasbit;
+    return DEREF(msg, hasbit / 8, char) | (1 << (hasbit % 8));
+  }
+}
+
+upb_msgval upb_msg_get(const upb_msg *msg, int field_index,
+                       const upb_msglayout *l) {
+  const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
+  int size = upb_msg_fieldsize(field);
+
+  if (upb_msg_inoneof(field)) {
+    if (*upb_msg_oneofcase(msg, field_index, l) == field->number) {
+      size_t ofs = l->data.oneofs[field->oneof_index].data_offset;
+      return upb_msgval_read(msg, ofs, size);
+    } else {
+      /* Return default. */
+      return upb_msgval_read(l->data.default_msg, field->offset, size);
+    }
+  } else {
+    return upb_msgval_read(msg, field->offset, size);
+  }
+}
+
+void upb_msg_set(upb_msg *msg, int field_index, upb_msgval val,
+                 const upb_msglayout *l) {
+  const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
+  int size = upb_msg_fieldsize(field);
+
+  if (upb_msg_inoneof(field)) {
+    size_t ofs = l->data.oneofs[field->oneof_index].data_offset;
+    *upb_msg_oneofcase(msg, field_index, l) = field->number;
+    upb_msgval_write(msg, ofs, val, size);
+  } else {
+    upb_msgval_write(msg, field->offset, val, size);
+  }
+}
+
+
+/** upb_array *****************************************************************/
+
+#define DEREF_ARR(arr, i, type) ((type*)arr->data)[i]
+
+size_t upb_array_sizeof(upb_fieldtype_t type) {
+  UPB_UNUSED(type);
+  return sizeof(upb_array);
+}
+
+void upb_array_init(upb_array *arr, upb_fieldtype_t type, upb_alloc *alloc) {
+  arr->type = type;
+  arr->data = NULL;
+  arr->len = 0;
+  arr->size = 0;
+  arr->element_size = upb_msgval_sizeof(type);
+  arr->alloc = alloc;
+}
+
+void upb_array_uninit(upb_array *arr) {
+  upb_free(arr->alloc, arr->data);
+}
+
+upb_array *upb_array_new(upb_fieldtype_t type, upb_alloc *a) {
+  upb_array *ret = upb_malloc(a, upb_array_sizeof(type));
+
+  if (ret) {
+    upb_array_init(ret, type, a);
+  }
+
+  return ret;
+}
+
+void upb_array_free(upb_array *arr) {
+  upb_array_uninit(arr);
+  upb_free(arr->alloc, arr);
+}
+
+size_t upb_array_size(const upb_array *arr) {
+  return arr->len;
+}
+
+upb_fieldtype_t upb_array_type(const upb_array *arr) {
+  return arr->type;
+}
+
+upb_msgval upb_array_get(const upb_array *arr, size_t i) {
+  UPB_ASSERT(i < arr->len);
+  return upb_msgval_read(arr->data, i * arr->element_size, arr->element_size);
+}
+
+bool upb_array_set(upb_array *arr, size_t i, upb_msgval val) {
+  UPB_ASSERT(i <= arr->len);
+
+  if (i == arr->len) {
+    /* Extending the array. */
+
+    if (i == arr->size) {
+      /* Need to reallocate. */
+      size_t new_size = UPB_MAX(arr->size * 2, 8);
+      size_t new_bytes = new_size * arr->element_size;
+      size_t old_bytes = arr->size * arr->element_size;
+      upb_msgval *new_data =
+          upb_realloc(arr->alloc, arr->data, old_bytes, new_bytes);
+
+      if (!new_data) {
+        return false;
+      }
+
+      arr->data = new_data;
+      arr->size = new_size;
+    }
+
+    arr->len = i + 1;
+  }
+
+  upb_msgval_write(arr->data, i * arr->element_size, val, arr->element_size);
+  return true;
+}
+
+
+/** upb_map *******************************************************************/
+
+struct upb_map {
+  upb_fieldtype_t key_type;
+  upb_fieldtype_t val_type;
+  /* We may want to optimize this to use inttable where possible, for greater
+   * efficiency and lower memory footprint. */
+  upb_strtable strtab;
+  upb_alloc *alloc;
+};
+
+static void upb_map_tokey(upb_fieldtype_t type, upb_msgval *key,
+                          const char **out_key, size_t *out_len) {
+  switch (type) {
+    case UPB_TYPE_STRING:
+      /* Point to string data of the input key. */
+      *out_key = key->str.data;
+      *out_len = key->str.size;
+      return;
+    case UPB_TYPE_BOOL:
+    case UPB_TYPE_INT32:
+    case UPB_TYPE_UINT32:
+    case UPB_TYPE_INT64:
+    case UPB_TYPE_UINT64:
+      /* Point to the key itself.  XXX: big-endian. */
+      *out_key = (const char*)key;
+      *out_len = upb_msgval_sizeof(type);
+      return;
+    case UPB_TYPE_BYTES:
+    case UPB_TYPE_DOUBLE:
+    case UPB_TYPE_ENUM:
+    case UPB_TYPE_FLOAT:
+    case UPB_TYPE_MESSAGE:
+      break;  /* Cannot be a map key. */
+  }
+  UPB_UNREACHABLE();
+}
+
+static upb_msgval upb_map_fromkey(upb_fieldtype_t type, const char *key,
+                                  size_t len) {
+  switch (type) {
+    case UPB_TYPE_STRING:
+      return upb_msgval_makestr(key, len);
+    case UPB_TYPE_BOOL:
+    case UPB_TYPE_INT32:
+    case UPB_TYPE_UINT32:
+    case UPB_TYPE_INT64:
+    case UPB_TYPE_UINT64:
+      return upb_msgval_read(key, 0, upb_msgval_sizeof(type));
+    case UPB_TYPE_BYTES:
+    case UPB_TYPE_DOUBLE:
+    case UPB_TYPE_ENUM:
+    case UPB_TYPE_FLOAT:
+    case UPB_TYPE_MESSAGE:
+      break;  /* Cannot be a map key. */
+  }
+  UPB_UNREACHABLE();
+}
+
+size_t upb_map_sizeof(upb_fieldtype_t ktype, upb_fieldtype_t vtype) {
+  /* Size does not currently depend on key/value type. */
+  UPB_UNUSED(ktype);
+  UPB_UNUSED(vtype);
+  return sizeof(upb_map);
+}
+
+bool upb_map_init(upb_map *map, upb_fieldtype_t ktype, upb_fieldtype_t vtype,
+                  upb_alloc *a) {
+  upb_ctype_t vtabtype = upb_fieldtotabtype(vtype);
+  UPB_ASSERT(upb_fieldtype_mapkeyok(ktype));
+  map->key_type = ktype;
+  map->val_type = vtype;
+  map->alloc = a;
+
+  if (!upb_strtable_init2(&map->strtab, vtabtype, a)) {
+    return false;
+  }
+
+  return true;
+}
+
+void upb_map_uninit(upb_map *map) {
+  upb_strtable_uninit2(&map->strtab, map->alloc);
+}
+
+upb_map *upb_map_new(upb_fieldtype_t ktype, upb_fieldtype_t vtype,
+                     upb_alloc *a) {
+  upb_map *map = upb_malloc(a, upb_map_sizeof(ktype, vtype));
+
+  if (!map) {
+    return NULL;
+  }
+
+  if (!upb_map_init(map, ktype, vtype, a)) {
+    return NULL;
+  }
+
+  return map;
+}
+
+void upb_map_free(upb_map *map) {
+  upb_map_uninit(map);
+  upb_free(map->alloc, map);
+}
+
+size_t upb_map_size(const upb_map *map) {
+  return upb_strtable_count(&map->strtab);
+}
+
+upb_fieldtype_t upb_map_keytype(const upb_map *map) {
+  return map->key_type;
+}
+
+upb_fieldtype_t upb_map_valuetype(const upb_map *map) {
+  return map->val_type;
+}
+
+bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) {
+  upb_value tabval;
+  const char *key_str;
+  size_t key_len;
+  bool ret;
+
+  upb_map_tokey(map->key_type, &key, &key_str, &key_len);
+  ret = upb_strtable_lookup2(&map->strtab, key_str, key_len, &tabval);
+  if (ret) {
+    memcpy(val, &tabval, sizeof(tabval));
+  }
+
+  return ret;
+}
+
+bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
+                 upb_msgval *removed) {
+  const char *key_str;
+  size_t key_len;
+  upb_value tabval = upb_toval(val);
+  upb_value removedtabval;
+  upb_alloc *a = map->alloc;
+
+  upb_map_tokey(map->key_type, &key, &key_str, &key_len);
+
+  /* TODO(haberman): add overwrite operation to minimize number of lookups. */
+  if (upb_strtable_lookup2(&map->strtab, key_str, key_len, NULL)) {
+    upb_strtable_remove3(&map->strtab, key_str, key_len, &removedtabval, a);
+    memcpy(&removed, &removedtabval, sizeof(removed));
+  }
+
+  return upb_strtable_insert3(&map->strtab, key_str, key_len, tabval, a);
+}
+
+bool upb_map_del(upb_map *map, upb_msgval key) {
+  const char *key_str;
+  size_t key_len;
+  upb_alloc *a = map->alloc;
+
+  upb_map_tokey(map->key_type, &key, &key_str, &key_len);
+  return upb_strtable_remove3(&map->strtab, key_str, key_len, NULL, a);
+}
+
+
+/** upb_mapiter ***************************************************************/
+
+struct upb_mapiter {
+  upb_strtable_iter iter;
+  upb_fieldtype_t key_type;
+};
+
+size_t upb_mapiter_sizeof() {
+  return sizeof(upb_mapiter);
+}
+
+void upb_mapiter_begin(upb_mapiter *i, const upb_map *map) {
+  upb_strtable_begin(&i->iter, &map->strtab);
+  i->key_type = map->key_type;
+}
+
+upb_mapiter *upb_mapiter_new(const upb_map *t, upb_alloc *a) {
+  upb_mapiter *ret = upb_malloc(a, upb_mapiter_sizeof());
+
+  if (!ret) {
+    return NULL;
+  }
+
+  upb_mapiter_begin(ret, t);
+  return ret;
+}
+
+void upb_mapiter_free(upb_mapiter *i, upb_alloc *a) {
+  upb_free(a, i);
+}
+
+void upb_mapiter_next(upb_mapiter *i) {
+  upb_strtable_next(&i->iter);
+}
+
+bool upb_mapiter_done(const upb_mapiter *i) {
+  return upb_strtable_done(&i->iter);
+}
+
+upb_msgval upb_mapiter_key(const upb_mapiter *i) {
+  return upb_map_fromkey(i->key_type, upb_strtable_iter_key(&i->iter),
+                         upb_strtable_iter_keylength(&i->iter));
+}
+
+upb_msgval upb_mapiter_value(const upb_mapiter *i) {
+  return upb_msgval_fromval(upb_strtable_iter_value(&i->iter));
+}
+
+void upb_mapiter_setdone(upb_mapiter *i) {
+  upb_strtable_iter_setdone(&i->iter);
+}
+
+bool upb_mapiter_isequal(const upb_mapiter *i1, const upb_mapiter *i2) {
+  return upb_strtable_iter_isequal(&i1->iter, &i2->iter);
+}
+
+
 /** Handlers for upb_msg ******************************************************/
 
 typedef struct {
@@ -4689,768 +5216,6 @@
   *hasbit = d->hasbit;
   return true;
 }
-
-
-bool upb_fieldtype_mapkeyok(upb_fieldtype_t type) {
-  return type == UPB_TYPE_BOOL || type == UPB_TYPE_INT32 ||
-         type == UPB_TYPE_UINT32 || type == UPB_TYPE_INT64 ||
-         type == UPB_TYPE_UINT64 || type == UPB_TYPE_STRING;
-}
-
-#define PTR_AT(msg, ofs, type) (type*)((char*)msg + ofs)
-#define VOIDPTR_AT(msg, ofs) PTR_AT(msg, ofs, void)
-#define ENCODE_MAX_NESTING 64
-#define CHECK_TRUE(x) if (!(x)) { return false; }
-
-/** upb_msgval ****************************************************************/
-
-#define upb_alignof(t) offsetof(struct { char c; t x; }, x)
-
-/* These functions will generate real memcpy() calls on ARM sadly, because
- * the compiler assumes they might not be aligned. */
-
-static upb_msgval upb_msgval_read(const void *p, size_t ofs,
-                                  uint8_t size) {
-  upb_msgval val;
-  p = (char*)p + ofs;
-  memcpy(&val, p, size);
-  return val;
-}
-
-static void upb_msgval_write(void *p, size_t ofs, upb_msgval val,
-                             uint8_t size) {
-  p = (char*)p + ofs;
-  memcpy(p, &val, size);
-}
-
-static size_t upb_msgval_sizeof(upb_fieldtype_t type) {
-  switch (type) {
-    case UPB_TYPE_DOUBLE:
-    case UPB_TYPE_INT64:
-    case UPB_TYPE_UINT64:
-      return 8;
-    case UPB_TYPE_ENUM:
-    case UPB_TYPE_INT32:
-    case UPB_TYPE_UINT32:
-    case UPB_TYPE_FLOAT:
-      return 4;
-    case UPB_TYPE_BOOL:
-      return 1;
-    case UPB_TYPE_MESSAGE:
-      return sizeof(void*);
-    case UPB_TYPE_BYTES:
-    case UPB_TYPE_STRING:
-      return sizeof(upb_stringview);
-  }
-  UPB_UNREACHABLE();
-}
-
-static uint8_t upb_msg_fieldsize(const upb_msglayout_field *field) {
-  if (field->label == UPB_LABEL_REPEATED) {
-    return sizeof(void*);
-  } else {
-    return upb_msgval_sizeof(upb_desctype_to_fieldtype[field->descriptortype]);
-  }
-}
-
-/* TODO(haberman): this is broken right now because upb_msgval can contain
- * a char* / size_t pair, which is too big for a upb_value.  To fix this
- * we'll probably need to dynamically allocate a upb_msgval and store a
- * pointer to that in the tables for extensions/maps. */
-static upb_value upb_toval(upb_msgval val) {
-  upb_value ret;
-  UPB_UNUSED(val);
-  memset(&ret, 0, sizeof(upb_value));  /* XXX */
-  return ret;
-}
-
-static upb_msgval upb_msgval_fromval(upb_value val) {
-  upb_msgval ret;
-  UPB_UNUSED(val);
-  memset(&ret, 0, sizeof(upb_msgval));  /* XXX */
-  return ret;
-}
-
-static upb_ctype_t upb_fieldtotabtype(upb_fieldtype_t type) {
-  switch (type) {
-    case UPB_TYPE_FLOAT: return UPB_CTYPE_FLOAT;
-    case UPB_TYPE_DOUBLE: return UPB_CTYPE_DOUBLE;
-    case UPB_TYPE_BOOL: return UPB_CTYPE_BOOL;
-    case UPB_TYPE_BYTES:
-    case UPB_TYPE_MESSAGE:
-    case UPB_TYPE_STRING: return UPB_CTYPE_CONSTPTR;
-    case UPB_TYPE_ENUM:
-    case UPB_TYPE_INT32: return UPB_CTYPE_INT32;
-    case UPB_TYPE_UINT32: return UPB_CTYPE_UINT32;
-    case UPB_TYPE_INT64: return UPB_CTYPE_INT64;
-    case UPB_TYPE_UINT64: return UPB_CTYPE_UINT64;
-    default: UPB_ASSERT(false); return 0;
-  }
-}
-
-
-/** upb_msg *******************************************************************/
-
-/* If we always read/write as a consistent type to each address, this shouldn't
- * violate aliasing.
- */
-#define DEREF(msg, ofs, type) *PTR_AT(msg, ofs, type)
-
-/* Internal members of a upb_msg.  We can change this without breaking binary
- * compatibility.  We put these before the user's data.  The user's upb_msg*
- * points after the upb_msg_internal. */
-
-/* Used when a message is not extendable. */
-typedef struct {
-  /* TODO(haberman): use pointer tagging so we we are slim when known unknown
-   * fields are not present. */
-  upb_arena *arena;
-  char *unknown;
-  size_t unknown_len;
-  size_t unknown_size;
-} upb_msg_internal;
-
-/* Used when a message is extendable. */
-typedef struct {
-  upb_inttable *extdict;
-  upb_msg_internal base;
-} upb_msg_internal_withext;
-
-static int upb_msg_internalsize(const upb_msglayout *l) {
-  return sizeof(upb_msg_internal) - l->extendable * sizeof(void *);
-}
-
-static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) {
-  return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
-}
-
-static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
-  return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
-}
-
-static upb_msg_internal_withext *upb_msg_getinternalwithext(
-    upb_msg *msg, const upb_msglayout *l) {
-  UPB_ASSERT(l->extendable);
-  return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext));
-}
-
-void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len) {
-  upb_msg_internal* in = upb_msg_getinternal(msg);
-  if (len > in->unknown_size - in->unknown_len) {
-    upb_alloc *alloc = upb_arena_alloc(in->arena);
-    size_t need = in->unknown_size + len;
-    size_t newsize = UPB_MAX(in->unknown_size * 2, need);
-    in->unknown = upb_realloc(alloc, in->unknown, in->unknown_size, newsize);
-    in->unknown_size = newsize;
-  }
-  memcpy(in->unknown + in->unknown_len, data, len);
-  in->unknown_len += len;
-}
-
-const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) {
-  const upb_msg_internal* in = upb_msg_getinternal_const(msg);
-  *len = in->unknown_len;
-  return in->unknown;
-}
-
-static const upb_msglayout_field *upb_msg_checkfield(int field_index,
-                                                     const upb_msglayout *l) {
-  UPB_ASSERT(field_index >= 0 && field_index < l->field_count);
-  return &l->fields[field_index];
-}
-
-static bool upb_msg_inoneof(const upb_msglayout_field *field) {
-  return field->presence < 0;
-}
-
-static uint32_t *upb_msg_oneofcase(const upb_msg *msg, int field_index,
-                                   const upb_msglayout *l) {
-  const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
-  UPB_ASSERT(upb_msg_inoneof(field));
-  return PTR_AT(msg, ~field->presence, uint32_t);
-}
-
-static size_t upb_msg_sizeof(const upb_msglayout *l) {
-  return l->size + upb_msg_internalsize(l);
-}
-
-upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) {
-  upb_alloc *alloc = upb_arena_alloc(a);
-  void *mem = upb_malloc(alloc, upb_msg_sizeof(l));
-  upb_msg_internal *in;
-  upb_msg *msg;
-
-  if (!mem) {
-    return NULL;
-  }
-
-  msg = VOIDPTR_AT(mem, upb_msg_internalsize(l));
-
-  /* Initialize normal members. */
-  memset(msg, 0, l->size);
-
-  /* Initialize internal members. */
-  in = upb_msg_getinternal(msg);
-  in->arena = a;
-  in->unknown = NULL;
-  in->unknown_len = 0;
-  in->unknown_size = 0;
-
-  if (l->extendable) {
-    upb_msg_getinternalwithext(msg, l)->extdict = NULL;
-  }
-
-  return msg;
-}
-
-upb_arena *upb_msg_arena(const upb_msg *msg) {
-  return upb_msg_getinternal_const(msg)->arena;
-}
-
-bool upb_msg_has(const upb_msg *msg,
-                 int field_index,
-                 const upb_msglayout *l) {
-  const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
-
-  UPB_ASSERT(field->presence);
-
-  if (upb_msg_inoneof(field)) {
-    /* Oneofs are set when the oneof number is set to this field. */
-    return *upb_msg_oneofcase(msg, field_index, l) == field->number;
-  } else {
-    /* Other fields are set when their hasbit is set. */
-    uint32_t hasbit = field->presence;
-    return DEREF(msg, hasbit / 8, char) | (1 << (hasbit % 8));
-  }
-}
-
-upb_msgval upb_msg_get(const upb_msg *msg, int field_index,
-                       const upb_msglayout *l) {
-  const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
-  int size = upb_msg_fieldsize(field);
-  return upb_msgval_read(msg, field->offset, size);
-}
-
-void upb_msg_set(upb_msg *msg, int field_index, upb_msgval val,
-                 const upb_msglayout *l) {
-  const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
-  int size = upb_msg_fieldsize(field);
-  upb_msgval_write(msg, field->offset, val, size);
-}
-
-
-/** upb_array *****************************************************************/
-
-#define DEREF_ARR(arr, i, type) ((type*)arr->data)[i]
-
-upb_array *upb_array_new(upb_fieldtype_t type, upb_arena *a) {
-  upb_alloc *alloc = upb_arena_alloc(a);
-  upb_array *ret = upb_malloc(alloc, sizeof(upb_array));
-
-  if (!ret) {
-    return NULL;
-  }
-
-  ret->type = type;
-  ret->data = NULL;
-  ret->len = 0;
-  ret->size = 0;
-  ret->element_size = upb_msgval_sizeof(type);
-  ret->arena = a;
-
-  return ret;
-}
-
-size_t upb_array_size(const upb_array *arr) {
-  return arr->len;
-}
-
-upb_fieldtype_t upb_array_type(const upb_array *arr) {
-  return arr->type;
-}
-
-upb_msgval upb_array_get(const upb_array *arr, size_t i) {
-  UPB_ASSERT(i < arr->len);
-  return upb_msgval_read(arr->data, i * arr->element_size, arr->element_size);
-}
-
-bool upb_array_set(upb_array *arr, size_t i, upb_msgval val) {
-  UPB_ASSERT(i <= arr->len);
-
-  if (i == arr->len) {
-    /* Extending the array. */
-
-    if (i == arr->size) {
-      /* Need to reallocate. */
-      size_t new_size = UPB_MAX(arr->size * 2, 8);
-      size_t new_bytes = new_size * arr->element_size;
-      size_t old_bytes = arr->size * arr->element_size;
-      upb_alloc *alloc = upb_arena_alloc(arr->arena);
-      upb_msgval *new_data =
-          upb_realloc(alloc, arr->data, old_bytes, new_bytes);
-
-      if (!new_data) {
-        return false;
-      }
-
-      arr->data = new_data;
-      arr->size = new_size;
-    }
-
-    arr->len = i + 1;
-  }
-
-  upb_msgval_write(arr->data, i * arr->element_size, val, arr->element_size);
-  return true;
-}
-
-
-/** upb_map *******************************************************************/
-
-struct upb_map {
-  upb_fieldtype_t key_type;
-  upb_fieldtype_t val_type;
-  /* We may want to optimize this to use inttable where possible, for greater
-   * efficiency and lower memory footprint. */
-  upb_strtable strtab;
-  upb_arena *arena;
-};
-
-static void upb_map_tokey(upb_fieldtype_t type, upb_msgval *key,
-                          const char **out_key, size_t *out_len) {
-  switch (type) {
-    case UPB_TYPE_STRING:
-      /* Point to string data of the input key. */
-      *out_key = key->str.data;
-      *out_len = key->str.size;
-      return;
-    case UPB_TYPE_BOOL:
-    case UPB_TYPE_INT32:
-    case UPB_TYPE_UINT32:
-    case UPB_TYPE_INT64:
-    case UPB_TYPE_UINT64:
-      /* Point to the key itself.  XXX: big-endian. */
-      *out_key = (const char*)key;
-      *out_len = upb_msgval_sizeof(type);
-      return;
-    case UPB_TYPE_BYTES:
-    case UPB_TYPE_DOUBLE:
-    case UPB_TYPE_ENUM:
-    case UPB_TYPE_FLOAT:
-    case UPB_TYPE_MESSAGE:
-      break;  /* Cannot be a map key. */
-  }
-  UPB_UNREACHABLE();
-}
-
-static upb_msgval upb_map_fromkey(upb_fieldtype_t type, const char *key,
-                                  size_t len) {
-  switch (type) {
-    case UPB_TYPE_STRING:
-      return upb_msgval_makestr(key, len);
-    case UPB_TYPE_BOOL:
-    case UPB_TYPE_INT32:
-    case UPB_TYPE_UINT32:
-    case UPB_TYPE_INT64:
-    case UPB_TYPE_UINT64:
-      return upb_msgval_read(key, 0, upb_msgval_sizeof(type));
-    case UPB_TYPE_BYTES:
-    case UPB_TYPE_DOUBLE:
-    case UPB_TYPE_ENUM:
-    case UPB_TYPE_FLOAT:
-    case UPB_TYPE_MESSAGE:
-      break;  /* Cannot be a map key. */
-  }
-  UPB_UNREACHABLE();
-}
-
-upb_map *upb_map_new(upb_fieldtype_t ktype, upb_fieldtype_t vtype,
-                     upb_arena *a) {
-  upb_ctype_t vtabtype = upb_fieldtotabtype(vtype);
-  upb_alloc *alloc = upb_arena_alloc(a);
-  upb_map *map = upb_malloc(alloc, sizeof(upb_map));
-
-  if (!map) {
-    return NULL;
-  }
-
-  UPB_ASSERT(upb_fieldtype_mapkeyok(ktype));
-  map->key_type = ktype;
-  map->val_type = vtype;
-  map->arena = a;
-
-  if (!upb_strtable_init2(&map->strtab, vtabtype, alloc)) {
-    return NULL;
-  }
-
-  return map;
-}
-
-size_t upb_map_size(const upb_map *map) {
-  return upb_strtable_count(&map->strtab);
-}
-
-upb_fieldtype_t upb_map_keytype(const upb_map *map) {
-  return map->key_type;
-}
-
-upb_fieldtype_t upb_map_valuetype(const upb_map *map) {
-  return map->val_type;
-}
-
-bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) {
-  upb_value tabval;
-  const char *key_str;
-  size_t key_len;
-  bool ret;
-
-  upb_map_tokey(map->key_type, &key, &key_str, &key_len);
-  ret = upb_strtable_lookup2(&map->strtab, key_str, key_len, &tabval);
-  if (ret) {
-    memcpy(val, &tabval, sizeof(tabval));
-  }
-
-  return ret;
-}
-
-bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
-                 upb_msgval *removed) {
-  const char *key_str;
-  size_t key_len;
-  upb_value tabval = upb_toval(val);
-  upb_value removedtabval;
-  upb_alloc *a = upb_arena_alloc(map->arena);
-
-  upb_map_tokey(map->key_type, &key, &key_str, &key_len);
-
-  /* TODO(haberman): add overwrite operation to minimize number of lookups. */
-  if (upb_strtable_lookup2(&map->strtab, key_str, key_len, NULL)) {
-    upb_strtable_remove3(&map->strtab, key_str, key_len, &removedtabval, a);
-    memcpy(&removed, &removedtabval, sizeof(removed));
-  }
-
-  return upb_strtable_insert3(&map->strtab, key_str, key_len, tabval, a);
-}
-
-bool upb_map_del(upb_map *map, upb_msgval key) {
-  const char *key_str;
-  size_t key_len;
-  upb_alloc *a = upb_arena_alloc(map->arena);
-
-  upb_map_tokey(map->key_type, &key, &key_str, &key_len);
-  return upb_strtable_remove3(&map->strtab, key_str, key_len, NULL, a);
-}
-
-
-/** upb_mapiter ***************************************************************/
-
-struct upb_mapiter {
-  upb_strtable_iter iter;
-  upb_fieldtype_t key_type;
-};
-
-size_t upb_mapiter_sizeof() {
-  return sizeof(upb_mapiter);
-}
-
-void upb_mapiter_begin(upb_mapiter *i, const upb_map *map) {
-  upb_strtable_begin(&i->iter, &map->strtab);
-  i->key_type = map->key_type;
-}
-
-upb_mapiter *upb_mapiter_new(const upb_map *t, upb_alloc *a) {
-  upb_mapiter *ret = upb_malloc(a, upb_mapiter_sizeof());
-
-  if (!ret) {
-    return NULL;
-  }
-
-  upb_mapiter_begin(ret, t);
-  return ret;
-}
-
-void upb_mapiter_free(upb_mapiter *i, upb_alloc *a) {
-  upb_free(a, i);
-}
-
-void upb_mapiter_next(upb_mapiter *i) {
-  upb_strtable_next(&i->iter);
-}
-
-bool upb_mapiter_done(const upb_mapiter *i) {
-  return upb_strtable_done(&i->iter);
-}
-
-upb_msgval upb_mapiter_key(const upb_mapiter *i) {
-  return upb_map_fromkey(i->key_type, upb_strtable_iter_key(&i->iter),
-                         upb_strtable_iter_keylength(&i->iter));
-}
-
-upb_msgval upb_mapiter_value(const upb_mapiter *i) {
-  return upb_msgval_fromval(upb_strtable_iter_value(&i->iter));
-}
-
-void upb_mapiter_setdone(upb_mapiter *i) {
-  upb_strtable_iter_setdone(&i->iter);
-}
-
-bool upb_mapiter_isequal(const upb_mapiter *i1, const upb_mapiter *i2) {
-  return upb_strtable_iter_isequal(&i1->iter, &i2->iter);
-}
-
-
-static bool is_power_of_two(size_t val) {
-  return (val & (val - 1)) == 0;
-}
-
-/* Align up to the given power of 2. */
-static size_t align_up(size_t val, size_t align) {
-  UPB_ASSERT(is_power_of_two(align));
-  return (val + align - 1) & ~(align - 1);
-}
-
-static size_t div_round_up(size_t n, size_t d) {
-  return (n + d - 1) / d;
-}
-
-static size_t upb_msgval_sizeof2(upb_fieldtype_t type) {
-  switch (type) {
-    case UPB_TYPE_DOUBLE:
-    case UPB_TYPE_INT64:
-    case UPB_TYPE_UINT64:
-      return 8;
-    case UPB_TYPE_ENUM:
-    case UPB_TYPE_INT32:
-    case UPB_TYPE_UINT32:
-    case UPB_TYPE_FLOAT:
-      return 4;
-    case UPB_TYPE_BOOL:
-      return 1;
-    case UPB_TYPE_MESSAGE:
-      return sizeof(void*);
-    case UPB_TYPE_BYTES:
-    case UPB_TYPE_STRING:
-      return sizeof(upb_stringview);
-  }
-  UPB_UNREACHABLE();
-}
-
-static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
-  if (upb_fielddef_isseq(f)) {
-    return sizeof(void*);
-  } else {
-    return upb_msgval_sizeof2(upb_fielddef_type(f));
-  }
-}
-
-
-/** upb_msglayout *************************************************************/
-
-static void upb_msglayout_free(upb_msglayout *l) {
-  upb_gfree(l);
-}
-
-static size_t upb_msglayout_place(upb_msglayout *l, size_t size) {
-  size_t ret;
-
-  l->size = align_up(l->size, size);
-  ret = l->size;
-  l->size += size;
-  return ret;
-}
-
-static bool upb_msglayout_init(const upb_msgdef *m,
-                               upb_msglayout *l,
-                               upb_msgfactory *factory) {
-  upb_msg_field_iter it;
-  upb_msg_oneof_iter oit;
-  size_t hasbit;
-  size_t submsg_count = 0;
-  const upb_msglayout **submsgs;
-  upb_msglayout_field *fields;
-
-  for (upb_msg_field_begin(&it, m);
-       !upb_msg_field_done(&it);
-       upb_msg_field_next(&it)) {
-    const upb_fielddef* f = upb_msg_iter_field(&it);
-    if (upb_fielddef_issubmsg(f)) {
-      submsg_count++;
-    }
-  }
-
-  memset(l, 0, sizeof(*l));
-
-  fields = upb_gmalloc(upb_msgdef_numfields(m) * sizeof(*fields));
-  submsgs = upb_gmalloc(submsg_count * sizeof(*submsgs));
-
-  if ((!fields && upb_msgdef_numfields(m)) ||
-      (!submsgs && submsg_count)) {
-    /* OOM. */
-    upb_gfree(fields);
-    upb_gfree(submsgs);
-    return false;
-  }
-
-  l->field_count = upb_msgdef_numfields(m);
-  l->fields = fields;
-  l->submsgs = submsgs;
-
-  /* Allocate data offsets in three stages:
-   *
-   * 1. hasbits.
-   * 2. regular fields.
-   * 3. oneof fields.
-   *
-   * OPT: There is a lot of room for optimization here to minimize the size.
-   */
-
-  /* Allocate hasbits and set basic field attributes. */
-  submsg_count = 0;
-  for (upb_msg_field_begin(&it, m), hasbit = 0;
-       !upb_msg_field_done(&it);
-       upb_msg_field_next(&it)) {
-    const upb_fielddef* f = upb_msg_iter_field(&it);
-    upb_msglayout_field *field = &fields[upb_fielddef_index(f)];
-
-    field->number = upb_fielddef_number(f);
-    field->descriptortype = upb_fielddef_descriptortype(f);
-    field->label = upb_fielddef_label(f);
-
-    if (upb_fielddef_issubmsg(f)) {
-      const upb_msglayout *sub_layout =
-          upb_msgfactory_getlayout(factory, upb_fielddef_msgsubdef(f));
-      field->submsg_index = submsg_count++;
-      submsgs[field->submsg_index] = sub_layout;
-    }
-
-    if (upb_fielddef_haspresence(f) && !upb_fielddef_containingoneof(f)) {
-      field->presence = (hasbit++);
-    } else {
-      field->presence = 0;
-    }
-  }
-
-  /* Account for space used by hasbits. */
-  l->size = div_round_up(hasbit, 8);
-
-  /* Allocate non-oneof fields. */
-  for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
-       upb_msg_field_next(&it)) {
-    const upb_fielddef* f = upb_msg_iter_field(&it);
-    size_t field_size = upb_msg_fielddefsize(f);
-    size_t index = upb_fielddef_index(f);
-
-    if (upb_fielddef_containingoneof(f)) {
-      /* Oneofs are handled separately below. */
-      continue;
-    }
-
-    fields[index].offset = upb_msglayout_place(l, field_size);
-  }
-
-  /* Allocate oneof fields.  Each oneof field consists of a uint32 for the case
-   * and space for the actual data. */
-  for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
-       upb_msg_oneof_next(&oit)) {
-    const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
-    upb_oneof_iter fit;
-
-    size_t case_size = sizeof(uint32_t);  /* Could potentially optimize this. */
-    size_t field_size = 0;
-    uint32_t case_offset;
-    uint32_t data_offset;
-
-    /* Calculate field size: the max of all field sizes. */
-    for (upb_oneof_begin(&fit, o);
-         !upb_oneof_done(&fit);
-         upb_oneof_next(&fit)) {
-      const upb_fielddef* f = upb_oneof_iter_field(&fit);
-      field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
-    }
-
-    /* Align and allocate case offset. */
-    case_offset = upb_msglayout_place(l, case_size);
-    data_offset = upb_msglayout_place(l, field_size);
-
-    for (upb_oneof_begin(&fit, o);
-         !upb_oneof_done(&fit);
-         upb_oneof_next(&fit)) {
-      const upb_fielddef* f = upb_oneof_iter_field(&fit);
-      fields[upb_fielddef_index(f)].offset = data_offset;
-      fields[upb_fielddef_index(f)].presence = ~case_offset;
-    }
-  }
-
-  /* Size of the entire structure should be a multiple of its greatest
-   * alignment.  TODO: track overall alignment for real? */
-  l->size = align_up(l->size, 8);
-
-  return true;
-}
-
-
-/** upb_msgfactory ************************************************************/
-
-struct upb_msgfactory {
-  const upb_symtab *symtab;  /* We own a ref. */
-  upb_inttable layouts;
-  upb_inttable mergehandlers;
-};
-
-upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab) {
-  upb_msgfactory *ret = upb_gmalloc(sizeof(*ret));
-
-  ret->symtab = symtab;
-  upb_inttable_init(&ret->layouts, UPB_CTYPE_PTR);
-  upb_inttable_init(&ret->mergehandlers, UPB_CTYPE_CONSTPTR);
-
-  return ret;
-}
-
-void upb_msgfactory_free(upb_msgfactory *f) {
-  upb_inttable_iter i;
-  upb_inttable_begin(&i, &f->layouts);
-  for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
-    upb_msglayout *l = upb_value_getptr(upb_inttable_iter_value(&i));
-    upb_msglayout_free(l);
-  }
-
-  upb_inttable_begin(&i, &f->mergehandlers);
-  for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
-    const upb_handlers *h = upb_value_getconstptr(upb_inttable_iter_value(&i));
-    upb_handlers_unref(h, f);
-  }
-
-  upb_inttable_uninit(&f->layouts);
-  upb_inttable_uninit(&f->mergehandlers);
-  upb_gfree(f);
-}
-
-const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f) {
-  return f->symtab;
-}
-
-const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
-                                              const upb_msgdef *m) {
-  upb_value v;
-  UPB_ASSERT(upb_symtab_lookupmsg(f->symtab, upb_msgdef_fullname(m)) == m);
-  UPB_ASSERT(!upb_msgdef_mapentry(m));
-
-  if (upb_inttable_lookupptr(&f->layouts, m, &v)) {
-    UPB_ASSERT(upb_value_getptr(v));
-    return upb_value_getptr(v);
-  } else {
-    /* In case of circular dependency, layout has to be inserted first. */
-    upb_msglayout *l = upb_gmalloc(sizeof(*l));
-    upb_msgfactory *mutable_f = (void*)f;
-    upb_inttable_insertptr(&mutable_f->layouts, m, upb_value_ptr(l));
-    UPB_ASSERT(l);
-    if (!upb_msglayout_init(m, l, f)) {
-      upb_msglayout_free(l);
-    }
-    return l;
-  }
-}
 /*
 ** upb::RefCounted Implementation
 **
@@ -6660,10 +6425,9 @@
 /* A simple "subclass" of upb_table that only adds a hash function for strings. */
 
 static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a) {
-  uint32_t len = (uint32_t) k2.str.len;
   char *str = upb_malloc(a, k2.str.len + sizeof(uint32_t) + 1);
   if (str == NULL) return 0;
-  memcpy(str, &len, sizeof(uint32_t));
+  memcpy(str, &k2.str.len, sizeof(uint32_t));
   memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len + 1);
   return (uintptr_t)str;
 }
@@ -7642,28 +7406,28 @@
 #endif
 
 static const upb_msgdef msgs[22] = {
-  UPB_MSGDEF_INIT("google.protobuf.DescriptorProto", 41, 8, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[0]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[0], &reftables[1]),
-  UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ExtensionRange", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[11], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[16]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[2], &reftables[3]),
-  UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ReservedRange", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[14], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[20]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[4], &reftables[5]),
-  UPB_MSGDEF_INIT("google.protobuf.EnumDescriptorProto", 12, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[17], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[24]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[6], &reftables[7]),
-  UPB_MSGDEF_INIT("google.protobuf.EnumOptions", 9, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[0], &arrays[21], 4, 2), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[28]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[8], &reftables[9]),
-  UPB_MSGDEF_INIT("google.protobuf.EnumValueDescriptorProto", 9, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[25], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[32]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[10], &reftables[11]),
-  UPB_MSGDEF_INIT("google.protobuf.EnumValueOptions", 8, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[2], &arrays[29], 2, 1), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[36]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[12], &reftables[13]),
-  UPB_MSGDEF_INIT("google.protobuf.FieldDescriptorProto", 24, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[40]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[14], &reftables[15]),
-  UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 13, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[42], 11, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[56]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[16], &reftables[17]),
-  UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 43, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[53], 13, 12), UPB_STRTABLE_INIT(12, 15, UPB_CTYPE_PTR, 4, &strentries[72]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[18], &reftables[19]),
-  UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 7, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[66], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[88]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[20], &reftables[21]),
-  UPB_MSGDEF_INIT("google.protobuf.FileOptions", 38, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 42, 17), UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[22], &reftables[23]),
-  UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 11, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[110], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[24], &reftables[25]),
-  UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 16, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[118], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[26], &reftables[27]),
-  UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 8, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[125], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[28], &reftables[29]),
-  UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[126], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[30], &reftables[31]),
-  UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 12, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[128], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[32], &reftables[33]),
-  UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 8, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[132], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[34], &reftables[35]),
-  UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 7, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[133], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[36], &reftables[37]),
-  UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 20, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[135], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[38], &reftables[39]),
-  UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 19, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[142], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[40], &reftables[41]),
-  UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[151], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[42], &reftables[43]),
+  UPB_MSGDEF_INIT("google.protobuf.DescriptorProto", 41, 8, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[0]), false, UPB_SYNTAX_PROTO2, &reftables[0], &reftables[1]),
+  UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ExtensionRange", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[11], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[16]), false, UPB_SYNTAX_PROTO2, &reftables[2], &reftables[3]),
+  UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ReservedRange", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[14], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[20]), false, UPB_SYNTAX_PROTO2, &reftables[4], &reftables[5]),
+  UPB_MSGDEF_INIT("google.protobuf.EnumDescriptorProto", 12, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[17], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[24]), false, UPB_SYNTAX_PROTO2, &reftables[6], &reftables[7]),
+  UPB_MSGDEF_INIT("google.protobuf.EnumOptions", 9, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[0], &arrays[21], 4, 2), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[28]), false, UPB_SYNTAX_PROTO2, &reftables[8], &reftables[9]),
+  UPB_MSGDEF_INIT("google.protobuf.EnumValueDescriptorProto", 9, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[25], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[32]), false, UPB_SYNTAX_PROTO2, &reftables[10], &reftables[11]),
+  UPB_MSGDEF_INIT("google.protobuf.EnumValueOptions", 8, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[2], &arrays[29], 2, 1), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[36]), false, UPB_SYNTAX_PROTO2, &reftables[12], &reftables[13]),
+  UPB_MSGDEF_INIT("google.protobuf.FieldDescriptorProto", 24, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[40]), false, UPB_SYNTAX_PROTO2, &reftables[14], &reftables[15]),
+  UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 13, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[42], 11, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[56]), false, UPB_SYNTAX_PROTO2, &reftables[16], &reftables[17]),
+  UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 43, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[53], 13, 12), UPB_STRTABLE_INIT(12, 15, UPB_CTYPE_PTR, 4, &strentries[72]), false, UPB_SYNTAX_PROTO2, &reftables[18], &reftables[19]),
+  UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 7, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[66], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[88]), false, UPB_SYNTAX_PROTO2, &reftables[20], &reftables[21]),
+  UPB_MSGDEF_INIT("google.protobuf.FileOptions", 38, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 42, 17), UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, &reftables[22], &reftables[23]),
+  UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 11, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[110], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, &reftables[24], &reftables[25]),
+  UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 16, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[118], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, &reftables[26], &reftables[27]),
+  UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 8, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[125], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, &reftables[28], &reftables[29]),
+  UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[126], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, &reftables[30], &reftables[31]),
+  UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 12, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[128], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, &reftables[32], &reftables[33]),
+  UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 8, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[132], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, &reftables[34], &reftables[35]),
+  UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 7, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[133], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, &reftables[36], &reftables[37]),
+  UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 20, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[135], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, &reftables[38], &reftables[39]),
+  UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 19, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[142], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, &reftables[40], &reftables[41]),
+  UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[151], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, &reftables[42], &reftables[43]),
 };
 
 static const upb_fielddef fields[107] = {
@@ -9231,7 +8995,6 @@
 
   upb_def_setfullname(upb_msgdef_upcast_mutable(m), name, NULL);
   upb_descreader_setscopename(r, name);  /* Passes ownership of name. */
-
   return n;
 }
 
@@ -12546,7 +12309,7 @@
   return r;
 }
 
-//#line 1 "upb/json/parser.rl"
+#line 1 "upb/json/parser.rl"
 /*
 ** upb::json::Parser (upb_json_parser)
 **
@@ -12572,66 +12335,12 @@
 #include <float.h>
 #include <math.h>
 #include <stdint.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-/* Need to define __USE_XOPEN before including time.h to make strptime work. */
-#ifndef __USE_XOPEN
-#define __USE_XOPEN
-#endif
-#include <time.h>
-
 
 #define UPB_JSON_MAX_DEPTH 64
 
-/* Type of value message */
-enum {
-  VALUE_NULLVALUE   = 0,
-  VALUE_NUMBERVALUE = 1,
-  VALUE_STRINGVALUE = 2,
-  VALUE_BOOLVALUE   = 3,
-  VALUE_STRUCTVALUE = 4,
-  VALUE_LISTVALUE   = 5
-};
-
-/* Forward declare */
-static bool is_top_level(upb_json_parser *p);
-static bool is_wellknown_msg(upb_json_parser *p, upb_wellknowntype_t type);
-static bool is_wellknown_field(upb_json_parser *p, upb_wellknowntype_t type);
-
-static bool is_number_wrapper_object(upb_json_parser *p);
-static bool does_number_wrapper_start(upb_json_parser *p);
-static bool does_number_wrapper_end(upb_json_parser *p);
-
-static bool is_string_wrapper_object(upb_json_parser *p);
-static bool does_string_wrapper_start(upb_json_parser *p);
-static bool does_string_wrapper_end(upb_json_parser *p);
-
-static void start_wrapper_object(upb_json_parser *p);
-static void end_wrapper_object(upb_json_parser *p);
-
-static void start_value_object(upb_json_parser *p, int value_type);
-static void end_value_object(upb_json_parser *p);
-
-static void start_listvalue_object(upb_json_parser *p);
-static void end_listvalue_object(upb_json_parser *p);
-
-static void start_structvalue_object(upb_json_parser *p);
-static void end_structvalue_object(upb_json_parser *p);
-
-static void start_object(upb_json_parser *p);
-static void end_object(upb_json_parser *p);
-
-static bool start_subobject(upb_json_parser *p);
-static void end_subobject(upb_json_parser *p);
-
-static void start_member(upb_json_parser *p);
-static void end_member(upb_json_parser *p);
-static bool end_membername(upb_json_parser *p);
-
-static const char eof_ch = 'e';
-
 typedef struct {
   upb_sink sink;
 
@@ -12659,9 +12368,6 @@
    * because |f| is the field in the *current* message (i.e., the map-entry
    * message itself), not the parent's field that leads to this map. */
   const upb_fielddef *mapfield;
-
-  /* True if the field to be parsed is unknown. */
-  bool is_unknown_field;
 } upb_jsonparser_frame;
 
 struct upb_json_parser {
@@ -12699,13 +12405,6 @@
 
   /* Intermediate result of parsing a unicode escape sequence. */
   uint32_t digit;
-
-  /* Whether to proceed if unknown field is met. */
-  bool ignore_json_unknown;
-
-  /* Cache for parsing timestamp due to base and zone are handled in different
-   * handlers. */
-  struct tm tm;
 };
 
 struct upb_json_parsermethod {
@@ -13214,71 +12913,21 @@
   return capture_end(p, ptr);
 }
 
-static bool start_number(upb_json_parser *p, const char *ptr) {
-  if (is_top_level(p)) {
-    if (is_number_wrapper_object(p)) {
-      start_wrapper_object(p);
-    } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
-      start_value_object(p, VALUE_NUMBERVALUE);
-    } else {
-      return false;
-    }
-  } else if (does_number_wrapper_start(p)) {
-    if (!start_subobject(p)) {
-      return false;
-    }
-    start_wrapper_object(p);
-  } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
-    if (!start_subobject(p)) {
-      return false;
-    }
-    start_value_object(p, VALUE_NUMBERVALUE);
-  }
-
+static void start_number(upb_json_parser *p, const char *ptr) {
   multipart_startaccum(p);
   capture_begin(p, ptr);
-  return true;
 }
 
 static bool parse_number(upb_json_parser *p, bool is_quoted);
 
-static bool end_number_nontop(upb_json_parser *p, const char *ptr) {
+static bool end_number(upb_json_parser *p, const char *ptr) {
   if (!capture_end(p, ptr)) {
     return false;
   }
 
-  if (p->top->f == NULL) {
-    multipart_end(p);
-    return true;
-  }
-
   return parse_number(p, false);
 }
 
-static bool end_number(upb_json_parser *p, const char *ptr) {
-  if (!end_number_nontop(p, ptr)) {
-    return false;
-  }
-
-  if (does_number_wrapper_end(p)) {
-    end_wrapper_object(p);
-    if (!is_top_level(p)) {
-      end_subobject(p);
-    }
-    return true;
-  }
-
-  if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
-    end_value_object(p);
-    if (!is_top_level(p)) {
-      end_subobject(p);
-    }
-    return true;
-  }
-
-  return true;
-}
-
 /* |buf| is NULL-terminated. |buf| itself will never include quotes;
  * |is_quoted| tells us whether this text originally appeared inside quotes. */
 static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
@@ -13428,10 +13077,6 @@
 static bool parser_putbool(upb_json_parser *p, bool val) {
   bool ok;
 
-  if (p->top->f == NULL) {
-    return true;
-  }
-
   if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL) {
     upb_status_seterrf(&p->status,
                        "Boolean value specified for non-bool field: %s",
@@ -13446,120 +13091,8 @@
   return true;
 }
 
-static bool end_bool(upb_json_parser *p, bool val) {
-  if (is_top_level(p)) {
-    if (is_wellknown_msg(p, UPB_WELLKNOWN_BOOLVALUE)) {
-      start_wrapper_object(p);
-    } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
-      start_value_object(p, VALUE_BOOLVALUE);
-    } else {
-      return false;
-    }
-  } else if (is_wellknown_field(p, UPB_WELLKNOWN_BOOLVALUE)) {
-    if (!start_subobject(p)) {
-      return false;
-    }
-    start_wrapper_object(p);
-  } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
-    if (!start_subobject(p)) {
-      return false;
-    }
-    start_value_object(p, VALUE_BOOLVALUE);
-  }
-
-  if (p->top->is_unknown_field) {
-    return true;
-  }
-
-  if (!parser_putbool(p, val)) {
-    return false;
-  }
-
-  if (is_wellknown_msg(p, UPB_WELLKNOWN_BOOLVALUE)) {
-    end_wrapper_object(p);
-    if (!is_top_level(p)) {
-      end_subobject(p);
-    }
-    return true;
-  }
-
-  if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
-    end_value_object(p);
-    if (!is_top_level(p)) {
-      end_subobject(p);
-    }
-    return true;
-  }
-
-  return true;
-}
-
-static bool end_null(upb_json_parser *p) {
-  const char *zero_ptr = "0";
-
-  if (is_top_level(p)) {
-    if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
-      start_value_object(p, VALUE_NULLVALUE);
-    } else {
-      return true;
-    }
-  } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
-    if (!start_subobject(p)) {
-      return false;
-    }
-    start_value_object(p, VALUE_NULLVALUE);
-  } else {
-    return true;
-  }
-
-  /* Fill null_value field. */
-  multipart_startaccum(p);
-  capture_begin(p, zero_ptr);
-  capture_end(p, zero_ptr + 1);
-  parse_number(p, false);
-
-  end_value_object(p);
-  if (!is_top_level(p)) {
-    end_subobject(p);
-  }
-
-  return true;
-}
-
 static bool start_stringval(upb_json_parser *p) {
-  if (is_top_level(p)) {
-    if (is_string_wrapper_object(p)) {
-      start_wrapper_object(p);
-    } else if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) ||
-               is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) {
-      start_object(p);
-    } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
-      start_value_object(p, VALUE_STRINGVALUE);
-    } else {
-      return false;
-    }
-  } else if (does_string_wrapper_start(p)) {
-    if (!start_subobject(p)) {
-      return false;
-    }
-    start_wrapper_object(p);
-  } else if (is_wellknown_field(p, UPB_WELLKNOWN_TIMESTAMP) ||
-             is_wellknown_field(p, UPB_WELLKNOWN_DURATION)) {
-    if (!start_subobject(p)) {
-      return false;
-    }
-    start_object(p);
-  } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
-    if (!start_subobject(p)) {
-      return false;
-    }
-    start_value_object(p, VALUE_STRINGVALUE);
-  }
-
-  if (p->top->f == NULL) {
-    multipart_startaccum(p);
-    return true;
-  }
+  UPB_ASSERT(p->top->f);
 
   if (upb_fielddef_isstring(p->top->f)) {
     upb_jsonparser_frame *inner;
@@ -13577,7 +13110,6 @@
     inner->name_table = NULL;
     inner->is_map = false;
     inner->is_mapentry = false;
-    inner->is_unknown_field = false;
     p->top = inner;
 
     if (upb_fielddef_type(p->top->f) == UPB_TYPE_STRING) {
@@ -13608,20 +13140,9 @@
   }
 }
 
-static bool end_stringval_nontop(upb_json_parser *p) {
+static bool end_stringval(upb_json_parser *p) {
   bool ok = true;
 
-  if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) ||
-      is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) {
-    multipart_end(p);
-    return true;
-  }
-
-  if (p->top->f == NULL) {
-    multipart_end(p);
-    return true;
-  }
-
   switch (upb_fielddef_type(p->top->f)) {
     case UPB_TYPE_BYTES:
       if (!base64_push(p, getsel_for_handlertype(p, UPB_HANDLER_STRING),
@@ -13681,291 +13202,6 @@
   return ok;
 }
 
-static bool end_stringval(upb_json_parser *p) {
-  if (!end_stringval_nontop(p)) {
-    return false;
-  }
-
-  if (does_string_wrapper_end(p)) {
-    end_wrapper_object(p);
-    if (!is_top_level(p)) {
-      end_subobject(p);
-    }
-    return true;
-  }
-
-  if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
-    end_value_object(p);
-    if (!is_top_level(p)) {
-      end_subobject(p);
-    }
-    return true;
-  }
-
-  if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) ||
-      is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) {
-    end_object(p);
-    if (!is_top_level(p)) {
-      end_subobject(p);
-    }
-    return true;
-  }
-
-  return true;
-}
-
-static void start_duration_base(upb_json_parser *p, const char *ptr) {
-  capture_begin(p, ptr);
-}
-
-static bool end_duration_base(upb_json_parser *p, const char *ptr) {
-  size_t len;
-  const char *buf;
-  char seconds_buf[14];
-  char nanos_buf[12];
-  char *end;
-  int64_t seconds = 0;
-  int32_t nanos = 0;
-  double val = 0.0;
-  const char *seconds_membername = "seconds";
-  const char *nanos_membername = "nanos";
-  size_t fraction_start;
-
-  if (!capture_end(p, ptr)) {
-    return false;
-  }
-
-  buf = accumulate_getptr(p, &len);
-
-  memset(seconds_buf, 0, 14);
-  memset(nanos_buf, 0, 12);
-
-  /* Find out base end. The maximus duration is 315576000000, which cannot be
-   * represented by double without losing precision. Thus, we need to handle
-   * fraction and base separately. */
-  for (fraction_start = 0; fraction_start < len && buf[fraction_start] != '.';
-       fraction_start++);
-
-  /* Parse base */
-  memcpy(seconds_buf, buf, fraction_start);
-  seconds = strtol(seconds_buf, &end, 10);
-  if (errno == ERANGE || end != seconds_buf + fraction_start) {
-    upb_status_seterrf(&p->status, "error parsing duration: %s",
-                       seconds_buf);
-    upb_env_reporterror(p->env, &p->status);
-    return false;
-  }
-
-  if (seconds > 315576000000) {
-    upb_status_seterrf(&p->status, "error parsing duration: "
-                                   "maximum acceptable value is "
-                                   "315576000000");
-    upb_env_reporterror(p->env, &p->status);
-    return false;
-  }
-
-  if (seconds < -315576000000) {
-    upb_status_seterrf(&p->status, "error parsing duration: "
-                                   "minimum acceptable value is "
-                                   "-315576000000");
-    upb_env_reporterror(p->env, &p->status);
-    return false;
-  }
-
-  /* Parse fraction */
-  nanos_buf[0] = '0';
-  memcpy(nanos_buf + 1, buf + fraction_start, len - fraction_start);
-  val = strtod(nanos_buf, &end);
-  if (errno == ERANGE || end != nanos_buf + len - fraction_start + 1) {
-    upb_status_seterrf(&p->status, "error parsing duration: %s",
-                       nanos_buf);
-    upb_env_reporterror(p->env, &p->status);
-    return false;
-  }
-
-  nanos = val * 1000000000;
-  if (seconds < 0) nanos = -nanos;
-
-  /* Clean up buffer */
-  multipart_end(p);
-
-  /* Set seconds */
-  start_member(p);
-  capture_begin(p, seconds_membername);
-  capture_end(p, seconds_membername + 7);
-  end_membername(p);
-  upb_sink_putint64(&p->top->sink, parser_getsel(p), seconds);
-  end_member(p);
-
-  /* Set nanos */
-  start_member(p);
-  capture_begin(p, nanos_membername);
-  capture_end(p, nanos_membername + 5);
-  end_membername(p);
-  upb_sink_putint32(&p->top->sink, parser_getsel(p), nanos);
-  end_member(p);
-
-  /* Continue previous environment */
-  multipart_startaccum(p);
-
-  return true;
-}
-
-static void start_timestamp_base(upb_json_parser *p, const char *ptr) {
-  capture_begin(p, ptr);
-}
-
-#define UPB_TIMESTAMP_BASE_SIZE 19
-
-static bool end_timestamp_base(upb_json_parser *p, const char *ptr) {
-  size_t len;
-  const char *buf;
-  /* 3 for GMT and 1 for ending 0 */
-  char timestamp_buf[UPB_TIMESTAMP_BASE_SIZE + 4];
-
-  if (!capture_end(p, ptr)) {
-    return false;
-  }
-
-  buf = accumulate_getptr(p, &len);
-  UPB_ASSERT(len == UPB_TIMESTAMP_BASE_SIZE);
-  memcpy(timestamp_buf, buf, UPB_TIMESTAMP_BASE_SIZE);
-  memcpy(timestamp_buf + UPB_TIMESTAMP_BASE_SIZE, "GMT", 3);
-  timestamp_buf[UPB_TIMESTAMP_BASE_SIZE + 3] = 0;
-
-  /* Parse seconds */
-  if (strptime(timestamp_buf, "%FT%H:%M:%S%Z", &p->tm) == NULL) {
-    upb_status_seterrf(&p->status, "error parsing timestamp: %s", buf);
-    upb_env_reporterror(p->env, &p->status);
-    return false;
-  }
-
-  /* Clean up buffer */
-  multipart_end(p);
-  multipart_startaccum(p);
-
-  return true;
-}
-
-static void start_timestamp_fraction(upb_json_parser *p, const char *ptr) {
-  capture_begin(p, ptr);
-}
-
-static bool end_timestamp_fraction(upb_json_parser *p, const char *ptr) {
-  size_t len;
-  const char *buf;
-  char nanos_buf[12];
-  char *end;
-  double val = 0.0;
-  int32_t nanos;
-  const char *nanos_membername = "nanos";
-
-  memset(nanos_buf, 0, 12);
-
-  if (!capture_end(p, ptr)) {
-    return false;
-  }
-
-  buf = accumulate_getptr(p, &len);
-
-  if (len > 10) {
-    upb_status_seterrf(&p->status,
-        "error parsing timestamp: at most 9-digit fraction.");
-    upb_env_reporterror(p->env, &p->status);
-    return false;
-  }
-
-  /* Parse nanos */
-  nanos_buf[0] = '0';
-  memcpy(nanos_buf + 1, buf, len);
-  val = strtod(nanos_buf, &end);
-
-  if (errno == ERANGE || end != nanos_buf + len + 1) {
-    upb_status_seterrf(&p->status, "error parsing timestamp nanos: %s",
-                       nanos_buf);
-    upb_env_reporterror(p->env, &p->status);
-    return false;
-  }
-
-  nanos = val * 1000000000;
-
-  /* Clean up previous environment */
-  multipart_end(p);
-
-  /* Set nanos */
-  start_member(p);
-  capture_begin(p, nanos_membername);
-  capture_end(p, nanos_membername + 5);
-  end_membername(p);
-  upb_sink_putint32(&p->top->sink, parser_getsel(p), nanos);
-  end_member(p);
-
-  /* Continue previous environment */
-  multipart_startaccum(p);
-
-  return true;
-}
-
-static void start_timestamp_zone(upb_json_parser *p, const char *ptr) {
-  capture_begin(p, ptr);
-}
-
-static bool end_timestamp_zone(upb_json_parser *p, const char *ptr) {
-  size_t len;
-  const char *buf;
-  int hours;
-  int64_t seconds;
-  const char *seconds_membername = "seconds";
-
-  if (!capture_end(p, ptr)) {
-    return false;
-  }
-
-  buf = accumulate_getptr(p, &len);
-
-  if (buf[0] != 'Z') {
-    if (sscanf(buf + 1, "%2d:00", &hours) != 1) {
-      upb_status_seterrf(&p->status, "error parsing timestamp offset");
-      upb_env_reporterror(p->env, &p->status);
-      return false;
-    }
-
-    if (buf[0] == '+') {
-      hours = -hours;
-    }
-
-    p->tm.tm_hour += hours;
-  }
-
-  /* Normalize tm */
-  seconds = mktime(&p->tm);
-
-  /* Check timestamp boundary */
-  if (seconds < -62135596800) {
-    upb_status_seterrf(&p->status, "error parsing timestamp: "
-                                   "minimum acceptable value is "
-                                   "0001-01-01T00:00:00Z");
-    upb_env_reporterror(p->env, &p->status);
-    return false;
-  }
-
-  /* Clean up previous environment */
-  multipart_end(p);
-
-  /* Set seconds */
-  start_member(p);
-  capture_begin(p, seconds_membername);
-  capture_end(p, seconds_membername + 7);
-  end_membername(p);
-  upb_sink_putint64(&p->top->sink, parser_getsel(p), seconds);
-  end_member(p);
-
-  /* Continue previous environment */
-  multipart_startaccum(p);
-
-  return true;
-}
-
 static void start_member(upb_json_parser *p) {
   UPB_ASSERT(!p->top->f);
   multipart_startaccum(p);
@@ -14069,7 +13305,6 @@
   inner->name_table = NULL;
   inner->mapfield = mapfield;
   inner->is_map = false;
-  inner->is_unknown_field = false;
 
   /* Don't set this to true *yet* -- we reuse parsing handlers below to push
    * the key field value to the sink, and these handlers will pop the frame
@@ -14099,12 +13334,6 @@
 static bool end_membername(upb_json_parser *p) {
   UPB_ASSERT(!p->top->f);
 
-  if (!p->top->m) {
-    p->top->is_unknown_field = true;
-    multipart_end(p);
-    return true;
-  }
-
   if (p->top->is_map) {
     return handle_mapentry(p);
   } else {
@@ -14117,11 +13346,9 @@
       multipart_end(p);
 
       return true;
-    } else if (p->ignore_json_unknown) {
-      p->top->is_unknown_field = true;
-      multipart_end(p);
-      return true;
     } else {
+      /* TODO(haberman): Ignore unknown fields if requested/configured to do
+       * so. */
       upb_status_seterrf(&p->status, "No such field: %.*s\n", (int)len, buf);
       upb_env_reporterror(p->env, &p->status);
       return false;
@@ -14150,23 +13377,10 @@
   }
 
   p->top->f = NULL;
-  p->top->is_unknown_field = false;
 }
 
 static bool start_subobject(upb_json_parser *p) {
-  if (p->top->is_unknown_field) {
-    upb_jsonparser_frame *inner;
-    if (!check_stack(p)) return false;
-
-    inner = p->top + 1;
-    inner->m = NULL;
-    inner->f = NULL;
-    inner->is_map = false;
-    inner->is_mapentry = false;
-    inner->is_unknown_field = false;
-    p->top = inner;
-    return true;
-  }
+  UPB_ASSERT(p->top->f);
 
   if (upb_fielddef_ismap(p->top->f)) {
     upb_jsonparser_frame *inner;
@@ -14185,7 +13399,6 @@
     inner->f = NULL;
     inner->is_map = true;
     inner->is_mapentry = false;
-    inner->is_unknown_field = false;
     p->top = inner;
 
     return true;
@@ -14206,7 +13419,6 @@
     inner->f = NULL;
     inner->is_map = false;
     inner->is_mapentry = false;
-    inner->is_unknown_field = false;
     p->top = inner;
 
     return true;
@@ -14219,35 +13431,7 @@
   }
 }
 
-static bool start_subobject_full(upb_json_parser *p) {
-  if (is_top_level(p)) {
-    if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
-      start_value_object(p, VALUE_STRUCTVALUE);
-      if (!start_subobject(p)) return false;
-      start_structvalue_object(p);
-    } else if (is_wellknown_msg(p, UPB_WELLKNOWN_STRUCT)) {
-      start_structvalue_object(p);
-    } else {
-      return true;
-    }
-  } else if (is_wellknown_field(p, UPB_WELLKNOWN_STRUCT)) {
-    if (!start_subobject(p)) return false;
-    start_structvalue_object(p);
-  } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
-    if (!start_subobject(p)) return false;
-    start_value_object(p, VALUE_STRUCTVALUE);
-    if (!start_subobject(p)) return false;
-    start_structvalue_object(p);
-  }
-
-  return start_subobject(p);
-}
-
 static void end_subobject(upb_json_parser *p) {
-  if (is_top_level(p)) {
-    return;
-  }
-
   if (p->top->is_map) {
     upb_selector_t sel;
     p->top--;
@@ -14255,30 +13439,9 @@
     upb_sink_endseq(&p->top->sink, sel);
   } else {
     upb_selector_t sel;
-    bool is_unknown = p->top->m == NULL;
     p->top--;
-    if (!is_unknown) {
-      sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG);
-      upb_sink_endsubmsg(&p->top->sink, sel);
-    }
-  }
-}
-
-static void end_subobject_full(upb_json_parser *p) {
-  end_subobject(p);
-
-  if (is_wellknown_msg(p, UPB_WELLKNOWN_STRUCT)) {
-    end_structvalue_object(p);
-    if (!is_top_level(p)) {
-      end_subobject(p);
-    }
-  }
-
-  if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
-    end_value_object(p);
-    if (!is_top_level(p)) {
-      end_subobject(p);
-    }
+    sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG);
+    upb_sink_endsubmsg(&p->top->sink, sel);
   }
 }
 
@@ -14286,38 +13449,7 @@
   upb_jsonparser_frame *inner;
   upb_selector_t sel;
 
-  if (is_top_level(p)) {
-    if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
-      start_value_object(p, VALUE_LISTVALUE);
-      if (!start_subobject(p)) return false;
-      start_listvalue_object(p);
-    } else if (is_wellknown_msg(p, UPB_WELLKNOWN_LISTVALUE)) {
-      start_listvalue_object(p);
-    } else {
-      return false;
-    }
-  } else if (is_wellknown_field(p, UPB_WELLKNOWN_LISTVALUE)) {
-    if (!start_subobject(p)) return false;
-    start_listvalue_object(p);
-  } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
-    if (!start_subobject(p)) return false;
-    start_value_object(p, VALUE_LISTVALUE);
-    if (!start_subobject(p)) return false;
-    start_listvalue_object(p);
-  }
-
-  if (p->top->is_unknown_field) {
-    inner = p->top + 1;
-    inner->m = NULL;
-    inner->name_table = NULL;
-    inner->f = NULL;
-    inner->is_map = false;
-    inner->is_mapentry = false;
-    inner->is_unknown_field = true;
-    p->top = inner;
-
-    return true;
-  }
+  UPB_ASSERT(p->top->f);
 
   if (!upb_fielddef_isseq(p->top->f)) {
     upb_status_seterrf(&p->status,
@@ -14337,7 +13469,6 @@
   inner->f = p->top->f;
   inner->is_map = false;
   inner->is_mapentry = false;
-  inner->is_unknown_field = false;
   p->top = inner;
 
   return true;
@@ -14349,37 +13480,18 @@
   UPB_ASSERT(p->top > p->stack);
 
   p->top--;
-
-  if (p->top->is_unknown_field) {
-    return;
-  }
-
   sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSEQ);
   upb_sink_endseq(&p->top->sink, sel);
-
-  if (is_wellknown_msg(p, UPB_WELLKNOWN_LISTVALUE)) {
-    end_listvalue_object(p);
-    if (!is_top_level(p)) {
-      end_subobject(p);
-    }
-  }
-
-  if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
-    end_value_object(p);
-    if (!is_top_level(p)) {
-      end_subobject(p);
-    }
-  }
 }
 
 static void start_object(upb_json_parser *p) {
-  if (!p->top->is_map && p->top->m != NULL) {
+  if (!p->top->is_map) {
     upb_sink_startmsg(&p->top->sink);
   }
 }
 
 static void end_object(upb_json_parser *p) {
-  if (!p->top->is_map && p->top->m != NULL) {
+  if (!p->top->is_map) {
     upb_status status;
     upb_status_clear(&status);
     upb_sink_endmsg(&p->top->sink, &status);
@@ -14389,149 +13501,6 @@
   }
 }
 
-static bool is_string_wrapper(const upb_msgdef *m) {
-  upb_wellknowntype_t type = upb_msgdef_wellknowntype(m);
-  return type == UPB_WELLKNOWN_STRINGVALUE ||
-         type == UPB_WELLKNOWN_BYTESVALUE;
-}
-
-static void start_wrapper_object(upb_json_parser *p) {
-  const char *membername = "value";
-
-  start_object(p);
-
-  /* Set up context for parsing value */
-  start_member(p);
-  capture_begin(p, membername);
-  capture_end(p, membername + 5);
-  end_membername(p);
-}
-
-static void end_wrapper_object(upb_json_parser *p) {
-  end_member(p);
-  end_object(p);
-}
-
-static void start_value_object(upb_json_parser *p, int value_type) {
-  const char *nullmember = "null_value";
-  const char *numbermember = "number_value";
-  const char *stringmember = "string_value";
-  const char *boolmember = "bool_value";
-  const char *structmember = "struct_value";
-  const char *listmember = "list_value";
-  const char *membername = "";
-
-  switch (value_type) {
-    case VALUE_NULLVALUE:
-      membername = nullmember;
-      break;
-    case VALUE_NUMBERVALUE:
-      membername = numbermember;
-      break;
-    case VALUE_STRINGVALUE:
-      membername = stringmember;
-      break;
-    case VALUE_BOOLVALUE:
-      membername = boolmember;
-      break;
-    case VALUE_STRUCTVALUE:
-      membername = structmember;
-      break;
-    case VALUE_LISTVALUE:
-      membername = listmember;
-      break;
-  }
-
-  start_object(p);
-
-  /* Set up context for parsing value */
-  start_member(p);
-  capture_begin(p, membername);
-  capture_end(p, membername + strlen(membername));
-  end_membername(p);
-}
-
-static void end_value_object(upb_json_parser *p) {
-  end_member(p);
-  end_object(p);
-}
-
-static void start_listvalue_object(upb_json_parser *p) {
-  const char *membername = "values";
-
-  start_object(p);
-
-  /* Set up context for parsing value */
-  start_member(p);
-  capture_begin(p, membername);
-  capture_end(p, membername + strlen(membername));
-  end_membername(p);
-}
-
-static void end_listvalue_object(upb_json_parser *p) {
-  end_member(p);
-  end_object(p);
-}
-
-static void start_structvalue_object(upb_json_parser *p) {
-  const char *membername = "fields";
-
-  start_object(p);
-
-  /* Set up context for parsing value */
-  start_member(p);
-  capture_begin(p, membername);
-  capture_end(p, membername + strlen(membername));
-  end_membername(p);
-}
-
-static void end_structvalue_object(upb_json_parser *p) {
-  end_member(p);
-  end_object(p);
-}
-
-static bool is_top_level(upb_json_parser *p) {
-  return p->top == p->stack && p->top->f == NULL && !p->top->is_unknown_field;
-}
-
-static bool is_wellknown_msg(upb_json_parser *p, upb_wellknowntype_t type) {
-  return p->top->m != NULL && upb_msgdef_wellknowntype(p->top->m) == type;
-}
-
-static bool is_wellknown_field(upb_json_parser *p, upb_wellknowntype_t type) {
-  return p->top->f != NULL &&
-         upb_fielddef_issubmsg(p->top->f) &&
-         (upb_msgdef_wellknowntype(upb_fielddef_msgsubdef(p->top->f))
-              == type);
-}
-
-static bool does_number_wrapper_start(upb_json_parser *p) {
-  return p->top->f != NULL &&
-         upb_fielddef_issubmsg(p->top->f) &&
-         upb_msgdef_isnumberwrapper(upb_fielddef_msgsubdef(p->top->f));
-}
-
-static bool does_number_wrapper_end(upb_json_parser *p) {
-  return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m);
-}
-
-static bool is_number_wrapper_object(upb_json_parser *p) {
-  return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m);
-}
-
-static bool does_string_wrapper_start(upb_json_parser *p) {
-  return p->top->f != NULL &&
-         upb_fielddef_issubmsg(p->top->f) &&
-         is_string_wrapper(upb_fielddef_msgsubdef(p->top->f));
-}
-
-static bool does_string_wrapper_end(upb_json_parser *p) {
-  return p->top->m != NULL && is_string_wrapper(p->top->m);
-}
-
-static bool is_string_wrapper_object(upb_json_parser *p) {
-  return p->top->m != NULL && is_string_wrapper(p->top->m);
-}
 
 #define CHECK_RETURN_TOP(x) if (!(x)) goto error
 
@@ -14554,262 +13523,160 @@
  * final state once, when the closing '"' is seen. */
 
 
-//#line 2147 "upb/json/parser.rl"
+#line 1310 "upb/json/parser.rl"
 
 
 
-//#line 2016 "upb/json/parser.c"
+#line 1222 "upb/json/parser.c"
 static const char _json_actions[] = {
-	0, 1, 0, 1, 1, 1, 3, 1, 
-	4, 1, 6, 1, 7, 1, 8, 1, 
-	9, 1, 10, 1, 11, 1, 12, 1, 
-	13, 1, 21, 1, 23, 1, 24, 1, 
-	25, 1, 27, 1, 28, 1, 30, 1, 
-	32, 1, 33, 1, 34, 1, 35, 1, 
-	36, 1, 38, 2, 4, 9, 2, 5, 
-	6, 2, 7, 3, 2, 7, 9, 2, 
-	14, 15, 2, 16, 17, 2, 18, 19, 
-	2, 22, 20, 2, 26, 37, 2, 29, 
-	2, 2, 30, 38, 2, 31, 20, 2, 
-	33, 38, 2, 34, 38, 2, 35, 38, 
-	3, 25, 22, 20, 3, 26, 37, 38, 
-	4, 14, 15, 16, 17
+	0, 1, 0, 1, 2, 1, 3, 1, 
+	5, 1, 6, 1, 7, 1, 8, 1, 
+	10, 1, 12, 1, 13, 1, 14, 1, 
+	15, 1, 16, 1, 17, 1, 21, 1, 
+	25, 1, 27, 2, 3, 8, 2, 4, 
+	5, 2, 6, 2, 2, 6, 8, 2, 
+	11, 9, 2, 13, 15, 2, 14, 15, 
+	2, 18, 1, 2, 19, 27, 2, 20, 
+	9, 2, 22, 27, 2, 23, 27, 2, 
+	24, 27, 2, 26, 27, 3, 14, 11, 
+	9
 };
 
-static const short _json_key_offsets[] = {
-	0, 0, 12, 13, 18, 23, 28, 29, 
-	30, 31, 32, 33, 34, 35, 36, 37, 
-	38, 43, 48, 49, 53, 58, 63, 68, 
-	72, 76, 79, 82, 84, 88, 92, 94, 
-	96, 101, 103, 105, 114, 120, 126, 132, 
-	138, 140, 144, 147, 149, 151, 154, 155, 
-	159, 161, 163, 165, 167, 168, 170, 172, 
-	173, 175, 177, 178, 180, 182, 183, 185, 
-	187, 188, 190, 192, 196, 198, 200, 201, 
-	202, 203, 204, 206, 211, 220, 221, 221, 
-	221, 226, 231, 236, 237, 238, 239, 240, 
-	240, 241, 242, 243, 243, 244, 245, 246, 
-	246, 251, 256, 257, 261, 266, 271, 276, 
-	280, 280, 283, 286, 289, 292, 295, 298, 
-	298, 298, 298, 298
+static const unsigned char _json_key_offsets[] = {
+	0, 0, 4, 9, 14, 15, 19, 24, 
+	29, 34, 38, 42, 45, 48, 50, 54, 
+	58, 60, 62, 67, 69, 71, 80, 86, 
+	92, 98, 104, 106, 115, 116, 116, 116, 
+	121, 126, 131, 132, 133, 134, 135, 135, 
+	136, 137, 138, 138, 139, 140, 141, 141, 
+	146, 151, 152, 156, 161, 166, 171, 175, 
+	175, 178, 178, 178
 };
 
 static const char _json_trans_keys[] = {
-	32, 34, 45, 91, 102, 110, 116, 123, 
-	9, 13, 48, 57, 34, 32, 93, 125, 
-	9, 13, 32, 44, 93, 9, 13, 32, 
-	93, 125, 9, 13, 97, 108, 115, 101, 
-	117, 108, 108, 114, 117, 101, 32, 34, 
-	125, 9, 13, 32, 34, 125, 9, 13, 
-	34, 32, 58, 9, 13, 32, 93, 125, 
-	9, 13, 32, 44, 125, 9, 13, 32, 
-	44, 125, 9, 13, 32, 34, 9, 13, 
-	45, 48, 49, 57, 48, 49, 57, 46, 
-	69, 101, 48, 57, 69, 101, 48, 57, 
-	43, 45, 48, 57, 48, 57, 48, 57, 
-	46, 69, 101, 48, 57, 34, 92, 34, 
-	92, 34, 47, 92, 98, 102, 110, 114, 
-	116, 117, 48, 57, 65, 70, 97, 102, 
+	32, 123, 9, 13, 32, 34, 125, 9, 
+	13, 32, 34, 125, 9, 13, 34, 32, 
+	58, 9, 13, 32, 93, 125, 9, 13, 
+	32, 44, 125, 9, 13, 32, 44, 125, 
+	9, 13, 32, 34, 9, 13, 45, 48, 
+	49, 57, 48, 49, 57, 46, 69, 101, 
+	48, 57, 69, 101, 48, 57, 43, 45, 
+	48, 57, 48, 57, 48, 57, 46, 69, 
+	101, 48, 57, 34, 92, 34, 92, 34, 
+	47, 92, 98, 102, 110, 114, 116, 117, 
 	48, 57, 65, 70, 97, 102, 48, 57, 
 	65, 70, 97, 102, 48, 57, 65, 70, 
-	97, 102, 34, 92, 45, 48, 49, 57, 
-	48, 49, 57, 46, 115, 48, 57, 115, 
-	48, 57, 34, 46, 115, 48, 57, 48, 
-	57, 48, 57, 48, 57, 48, 57, 45, 
-	48, 57, 48, 57, 45, 48, 57, 48, 
-	57, 84, 48, 57, 48, 57, 58, 48, 
-	57, 48, 57, 58, 48, 57, 48, 57, 
-	43, 45, 46, 90, 48, 57, 48, 57, 
-	58, 48, 48, 34, 48, 57, 43, 45, 
-	90, 48, 57, 34, 45, 91, 102, 110, 
-	116, 123, 48, 57, 34, 32, 93, 125, 
-	9, 13, 32, 44, 93, 9, 13, 32, 
-	93, 125, 9, 13, 97, 108, 115, 101, 
-	117, 108, 108, 114, 117, 101, 32, 34, 
-	125, 9, 13, 32, 34, 125, 9, 13, 
-	34, 32, 58, 9, 13, 32, 93, 125, 
-	9, 13, 32, 44, 125, 9, 13, 32, 
-	44, 125, 9, 13, 32, 34, 9, 13, 
-	32, 9, 13, 32, 9, 13, 32, 9, 
-	13, 32, 9, 13, 32, 9, 13, 32, 
+	97, 102, 48, 57, 65, 70, 97, 102, 
+	34, 92, 34, 45, 91, 102, 110, 116, 
+	123, 48, 57, 34, 32, 93, 125, 9, 
+	13, 32, 44, 93, 9, 13, 32, 93, 
+	125, 9, 13, 97, 108, 115, 101, 117, 
+	108, 108, 114, 117, 101, 32, 34, 125, 
+	9, 13, 32, 34, 125, 9, 13, 34, 
+	32, 58, 9, 13, 32, 93, 125, 9, 
+	13, 32, 44, 125, 9, 13, 32, 44, 
+	125, 9, 13, 32, 34, 9, 13, 32, 
 	9, 13, 0
 };
 
 static const char _json_single_lengths[] = {
-	0, 8, 1, 3, 3, 3, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	3, 3, 1, 2, 3, 3, 3, 2, 
-	2, 1, 3, 0, 2, 2, 0, 0, 
-	3, 2, 2, 9, 0, 0, 0, 0, 
-	2, 2, 1, 2, 0, 1, 1, 2, 
-	0, 0, 0, 0, 1, 0, 0, 1, 
-	0, 0, 1, 0, 0, 1, 0, 0, 
-	1, 0, 0, 4, 0, 0, 1, 1, 
-	1, 1, 0, 3, 7, 1, 0, 0, 
-	3, 3, 3, 1, 1, 1, 1, 0, 
-	1, 1, 1, 0, 1, 1, 1, 0, 
-	3, 3, 1, 2, 3, 3, 3, 2, 
-	0, 1, 1, 1, 1, 1, 1, 0, 
-	0, 0, 0, 0
+	0, 2, 3, 3, 1, 2, 3, 3, 
+	3, 2, 2, 1, 3, 0, 2, 2, 
+	0, 0, 3, 2, 2, 9, 0, 0, 
+	0, 0, 2, 7, 1, 0, 0, 3, 
+	3, 3, 1, 1, 1, 1, 0, 1, 
+	1, 1, 0, 1, 1, 1, 0, 3, 
+	3, 1, 2, 3, 3, 3, 2, 0, 
+	1, 0, 0, 0
 };
 
 static const char _json_range_lengths[] = {
-	0, 2, 0, 1, 1, 1, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	1, 1, 0, 1, 1, 1, 1, 1, 
-	1, 1, 0, 1, 1, 1, 1, 1, 
-	1, 0, 0, 0, 3, 3, 3, 3, 
-	0, 1, 1, 0, 1, 1, 0, 1, 
-	1, 1, 1, 1, 0, 1, 1, 0, 
-	1, 1, 0, 1, 1, 0, 1, 1, 
-	0, 1, 1, 0, 1, 1, 0, 0, 
-	0, 0, 1, 1, 1, 0, 0, 0, 
-	1, 1, 1, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	1, 1, 0, 1, 1, 1, 1, 1, 
-	0, 1, 1, 1, 1, 1, 1, 0, 
-	0, 0, 0, 0
+	0, 1, 1, 1, 0, 1, 1, 1, 
+	1, 1, 1, 1, 0, 1, 1, 1, 
+	1, 1, 1, 0, 0, 0, 3, 3, 
+	3, 3, 0, 1, 0, 0, 0, 1, 
+	1, 1, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 1, 
+	1, 0, 1, 1, 1, 1, 1, 0, 
+	1, 0, 0, 0
 };
 
 static const short _json_index_offsets[] = {
-	0, 0, 11, 13, 18, 23, 28, 30, 
-	32, 34, 36, 38, 40, 42, 44, 46, 
-	48, 53, 58, 60, 64, 69, 74, 79, 
-	83, 87, 90, 94, 96, 100, 104, 106, 
-	108, 113, 116, 119, 129, 133, 137, 141, 
-	145, 148, 152, 155, 158, 160, 163, 165, 
-	169, 171, 173, 175, 177, 179, 181, 183, 
-	185, 187, 189, 191, 193, 195, 197, 199, 
-	201, 203, 205, 207, 212, 214, 216, 218, 
-	220, 222, 224, 226, 231, 240, 242, 243, 
-	244, 249, 254, 259, 261, 263, 265, 267, 
-	268, 270, 272, 274, 275, 277, 279, 281, 
-	282, 287, 292, 294, 298, 303, 308, 313, 
-	317, 318, 321, 324, 327, 330, 333, 336, 
-	337, 338, 339, 340
+	0, 0, 4, 9, 14, 16, 20, 25, 
+	30, 35, 39, 43, 46, 50, 52, 56, 
+	60, 62, 64, 69, 72, 75, 85, 89, 
+	93, 97, 101, 104, 113, 115, 116, 117, 
+	122, 127, 132, 134, 136, 138, 140, 141, 
+	143, 145, 147, 148, 150, 152, 154, 155, 
+	160, 165, 167, 171, 176, 181, 186, 190, 
+	191, 194, 195, 196
 };
 
-static const unsigned char _json_indicies[] = {
-	0, 2, 3, 4, 5, 6, 7, 8, 
-	0, 3, 1, 9, 1, 11, 12, 1, 
-	11, 10, 13, 14, 12, 13, 1, 14, 
-	1, 1, 14, 10, 15, 1, 16, 1, 
-	17, 1, 18, 1, 19, 1, 20, 1, 
-	21, 1, 22, 1, 23, 1, 24, 1, 
-	25, 26, 27, 25, 1, 28, 29, 30, 
-	28, 1, 31, 1, 32, 33, 32, 1, 
-	33, 1, 1, 33, 34, 35, 36, 37, 
-	35, 1, 38, 39, 30, 38, 1, 39, 
-	29, 39, 1, 40, 41, 42, 1, 41, 
-	42, 1, 44, 45, 45, 43, 46, 1, 
-	45, 45, 46, 43, 47, 47, 48, 1, 
-	48, 1, 48, 43, 44, 45, 45, 42, 
-	43, 50, 51, 49, 53, 54, 52, 55, 
-	55, 55, 55, 55, 55, 55, 55, 56, 
-	1, 57, 57, 57, 1, 58, 58, 58, 
-	1, 59, 59, 59, 1, 60, 60, 60, 
-	1, 62, 63, 61, 64, 65, 66, 1, 
-	67, 68, 1, 69, 70, 1, 71, 1, 
-	70, 71, 1, 72, 1, 69, 70, 68, 
-	1, 73, 1, 74, 1, 75, 1, 76, 
-	1, 77, 1, 78, 1, 79, 1, 80, 
-	1, 81, 1, 82, 1, 83, 1, 84, 
-	1, 85, 1, 86, 1, 87, 1, 88, 
-	1, 89, 1, 90, 1, 91, 1, 92, 
-	92, 93, 94, 1, 95, 1, 96, 1, 
-	97, 1, 98, 1, 99, 1, 100, 1, 
-	101, 1, 102, 102, 103, 101, 1, 104, 
-	105, 106, 107, 108, 109, 110, 105, 1, 
-	111, 1, 112, 113, 115, 116, 1, 115, 
-	114, 117, 118, 116, 117, 1, 118, 1, 
-	1, 118, 114, 119, 1, 120, 1, 121, 
-	1, 122, 1, 123, 124, 1, 125, 1, 
-	126, 1, 127, 128, 1, 129, 1, 130, 
-	1, 131, 132, 133, 134, 132, 1, 135, 
-	136, 137, 135, 1, 138, 1, 139, 140, 
-	139, 1, 140, 1, 1, 140, 141, 142, 
-	143, 144, 142, 1, 145, 146, 137, 145, 
-	1, 146, 136, 146, 1, 147, 148, 148, 
-	1, 149, 149, 1, 150, 150, 1, 151, 
-	151, 1, 152, 152, 1, 153, 153, 1, 
-	1, 1, 1, 1, 1, 0
+static const char _json_indicies[] = {
+	0, 2, 0, 1, 3, 4, 5, 3, 
+	1, 6, 7, 8, 6, 1, 9, 1, 
+	10, 11, 10, 1, 11, 1, 1, 11, 
+	12, 13, 14, 15, 13, 1, 16, 17, 
+	8, 16, 1, 17, 7, 17, 1, 18, 
+	19, 20, 1, 19, 20, 1, 22, 23, 
+	23, 21, 24, 1, 23, 23, 24, 21, 
+	25, 25, 26, 1, 26, 1, 26, 21, 
+	22, 23, 23, 20, 21, 28, 29, 27, 
+	31, 32, 30, 33, 33, 33, 33, 33, 
+	33, 33, 33, 34, 1, 35, 35, 35, 
+	1, 36, 36, 36, 1, 37, 37, 37, 
+	1, 38, 38, 38, 1, 40, 41, 39, 
+	42, 43, 44, 45, 46, 47, 48, 43, 
+	1, 49, 1, 50, 51, 53, 54, 1, 
+	53, 52, 55, 56, 54, 55, 1, 56, 
+	1, 1, 56, 52, 57, 1, 58, 1, 
+	59, 1, 60, 1, 61, 62, 1, 63, 
+	1, 64, 1, 65, 66, 1, 67, 1, 
+	68, 1, 69, 70, 71, 72, 70, 1, 
+	73, 74, 75, 73, 1, 76, 1, 77, 
+	78, 77, 1, 78, 1, 1, 78, 79, 
+	80, 81, 82, 80, 1, 83, 84, 75, 
+	83, 1, 84, 74, 84, 1, 85, 86, 
+	86, 1, 1, 1, 1, 0
 };
 
 static const char _json_trans_targs[] = {
-	1, 0, 2, 106, 3, 6, 10, 13, 
-	16, 105, 4, 3, 105, 4, 5, 7, 
-	8, 9, 107, 11, 12, 108, 14, 15, 
-	109, 17, 18, 110, 17, 18, 110, 19, 
-	19, 20, 21, 22, 23, 110, 22, 23, 
-	25, 26, 32, 111, 27, 29, 28, 30, 
-	31, 34, 112, 35, 34, 112, 35, 33, 
-	36, 37, 38, 39, 40, 34, 112, 35, 
-	42, 43, 47, 43, 47, 44, 46, 45, 
-	113, 49, 50, 51, 52, 53, 54, 55, 
-	56, 57, 58, 59, 60, 61, 62, 63, 
-	64, 65, 66, 67, 68, 74, 73, 69, 
-	70, 71, 72, 73, 114, 75, 68, 73, 
-	77, 79, 80, 83, 88, 92, 96, 78, 
-	115, 115, 81, 80, 78, 81, 82, 84, 
-	85, 86, 87, 115, 89, 90, 91, 115, 
-	93, 94, 95, 115, 97, 98, 104, 97, 
-	98, 104, 99, 99, 100, 101, 102, 103, 
-	104, 102, 103, 115, 105, 105, 105, 105, 
-	105, 105
+	1, 0, 2, 3, 4, 56, 3, 4, 
+	56, 5, 5, 6, 7, 8, 9, 56, 
+	8, 9, 11, 12, 18, 57, 13, 15, 
+	14, 16, 17, 20, 58, 21, 20, 58, 
+	21, 19, 22, 23, 24, 25, 26, 20, 
+	58, 21, 28, 30, 31, 34, 39, 43, 
+	47, 29, 59, 59, 32, 31, 29, 32, 
+	33, 35, 36, 37, 38, 59, 40, 41, 
+	42, 59, 44, 45, 46, 59, 48, 49, 
+	55, 48, 49, 55, 50, 50, 51, 52, 
+	53, 54, 55, 53, 54, 59, 56
 };
 
 static const char _json_trans_actions[] = {
-	0, 0, 84, 78, 33, 0, 0, 0, 
-	47, 39, 25, 0, 35, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 31, 96, 31, 0, 72, 0, 27, 
-	0, 0, 25, 29, 29, 29, 0, 0, 
-	0, 0, 0, 3, 0, 0, 0, 0, 
-	0, 5, 15, 0, 0, 51, 7, 13, 
-	0, 54, 9, 9, 9, 57, 60, 11, 
-	17, 17, 17, 0, 0, 0, 19, 0, 
-	21, 23, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 104, 63, 104, 0, 
-	0, 0, 0, 0, 69, 0, 66, 66, 
-	84, 78, 33, 0, 0, 0, 47, 39, 
-	49, 81, 25, 0, 35, 0, 0, 0, 
-	0, 0, 0, 90, 0, 0, 0, 93, 
-	0, 0, 0, 87, 31, 96, 31, 0, 
-	72, 0, 27, 0, 0, 25, 29, 29, 
-	29, 0, 0, 100, 0, 37, 43, 45, 
-	41, 75
-};
-
-static const char _json_eof_actions[] = {
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 1, 0, 1, 0, 0, 1, 
-	1, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 37, 43, 45, 41, 75, 0, 
-	0, 0, 0, 0
+	0, 0, 0, 21, 77, 53, 0, 47, 
+	23, 17, 0, 0, 15, 19, 19, 50, 
+	0, 0, 0, 0, 0, 1, 0, 0, 
+	0, 0, 0, 3, 13, 0, 0, 35, 
+	5, 11, 0, 38, 7, 7, 7, 41, 
+	44, 9, 62, 56, 25, 0, 0, 0, 
+	31, 29, 33, 59, 15, 0, 27, 0, 
+	0, 0, 0, 0, 0, 68, 0, 0, 
+	0, 71, 0, 0, 0, 65, 21, 77, 
+	53, 0, 47, 23, 17, 0, 0, 15, 
+	19, 19, 50, 0, 0, 74, 0
 };
 
 static const int json_start = 1;
 
-static const int json_en_number_machine = 24;
-static const int json_en_string_machine = 33;
-static const int json_en_duration_machine = 41;
-static const int json_en_timestamp_machine = 48;
-static const int json_en_value_machine = 76;
+static const int json_en_number_machine = 10;
+static const int json_en_string_machine = 19;
+static const int json_en_value_machine = 27;
 static const int json_en_main = 1;
 
 
-//#line 2150 "upb/json/parser.rl"
+#line 1313 "upb/json/parser.rl"
 
 size_t parse(void *closure, const void *hd, const char *buf, size_t size,
              const upb_bufhandle *handle) {
@@ -14822,7 +13689,6 @@
 
   const char *p = buf;
   const char *pe = buf + size;
-  const char *eof = &eof_ch;
 
   parser->handle = handle;
 
@@ -14832,7 +13698,7 @@
   capture_resume(parser, buf);
 
   
-//#line 2290 "upb/json/parser.c"
+#line 1393 "upb/json/parser.c"
 	{
 	int _klen;
 	unsigned int _trans;
@@ -14906,167 +13772,119 @@
 	{
 		switch ( *_acts++ )
 		{
-	case 1:
-//#line 2021 "upb/json/parser.rl"
+	case 0:
+#line 1225 "upb/json/parser.rl"
 	{ p--; {cs = stack[--top]; goto _again;} }
 	break;
+	case 1:
+#line 1226 "upb/json/parser.rl"
+	{ p--; {stack[top++] = cs; cs = 10; goto _again;} }
+	break;
 	case 2:
-//#line 2023 "upb/json/parser.rl"
-	{ p--; {stack[top++] = cs; cs = 24; goto _again;} }
-	break;
-	case 3:
-//#line 2027 "upb/json/parser.rl"
+#line 1230 "upb/json/parser.rl"
 	{ start_text(parser, p); }
 	break;
-	case 4:
-//#line 2028 "upb/json/parser.rl"
+	case 3:
+#line 1231 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_text(parser, p)); }
 	break;
-	case 5:
-//#line 2034 "upb/json/parser.rl"
+	case 4:
+#line 1237 "upb/json/parser.rl"
 	{ start_hex(parser); }
 	break;
-	case 6:
-//#line 2035 "upb/json/parser.rl"
+	case 5:
+#line 1238 "upb/json/parser.rl"
 	{ hexdigit(parser, p); }
 	break;
-	case 7:
-//#line 2036 "upb/json/parser.rl"
+	case 6:
+#line 1239 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_hex(parser)); }
 	break;
-	case 8:
-//#line 2042 "upb/json/parser.rl"
+	case 7:
+#line 1245 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(escape(parser, p)); }
 	break;
-	case 9:
-//#line 2048 "upb/json/parser.rl"
+	case 8:
+#line 1251 "upb/json/parser.rl"
 	{ p--; {cs = stack[--top]; goto _again;} }
 	break;
+	case 9:
+#line 1254 "upb/json/parser.rl"
+	{ {stack[top++] = cs; cs = 19; goto _again;} }
+	break;
 	case 10:
-//#line 2060 "upb/json/parser.rl"
-	{ start_duration_base(parser, p); }
+#line 1256 "upb/json/parser.rl"
+	{ p--; {stack[top++] = cs; cs = 27; goto _again;} }
 	break;
 	case 11:
-//#line 2061 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_duration_base(parser, p)); }
-	break;
-	case 12:
-//#line 2063 "upb/json/parser.rl"
-	{ p--; {cs = stack[--top]; goto _again;} }
-	break;
-	case 13:
-//#line 2068 "upb/json/parser.rl"
-	{ start_timestamp_base(parser, p); }
-	break;
-	case 14:
-//#line 2069 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_timestamp_base(parser, p)); }
-	break;
-	case 15:
-//#line 2071 "upb/json/parser.rl"
-	{ start_timestamp_fraction(parser, p); }
-	break;
-	case 16:
-//#line 2072 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_timestamp_fraction(parser, p)); }
-	break;
-	case 17:
-//#line 2074 "upb/json/parser.rl"
-	{ start_timestamp_zone(parser, p); }
-	break;
-	case 18:
-//#line 2075 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_timestamp_zone(parser, p)); }
-	break;
-	case 19:
-//#line 2077 "upb/json/parser.rl"
-	{ p--; {cs = stack[--top]; goto _again;} }
-	break;
-	case 20:
-//#line 2082 "upb/json/parser.rl"
-	{
-        if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) {
-          {stack[top++] = cs; cs = 48; goto _again;}
-        } else if (is_wellknown_msg(parser, UPB_WELLKNOWN_DURATION)) {
-          {stack[top++] = cs; cs = 41; goto _again;}
-        } else {
-          {stack[top++] = cs; cs = 33; goto _again;}
-        }
-      }
-	break;
-	case 21:
-//#line 2093 "upb/json/parser.rl"
-	{ p--; {stack[top++] = cs; cs = 76; goto _again;} }
-	break;
-	case 22:
-//#line 2098 "upb/json/parser.rl"
+#line 1261 "upb/json/parser.rl"
 	{ start_member(parser); }
 	break;
-	case 23:
-//#line 2099 "upb/json/parser.rl"
+	case 12:
+#line 1262 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_membername(parser)); }
 	break;
-	case 24:
-//#line 2102 "upb/json/parser.rl"
+	case 13:
+#line 1265 "upb/json/parser.rl"
 	{ end_member(parser); }
 	break;
-	case 25:
-//#line 2108 "upb/json/parser.rl"
+	case 14:
+#line 1271 "upb/json/parser.rl"
 	{ start_object(parser); }
 	break;
-	case 26:
-//#line 2111 "upb/json/parser.rl"
+	case 15:
+#line 1274 "upb/json/parser.rl"
 	{ end_object(parser); }
 	break;
-	case 27:
-//#line 2117 "upb/json/parser.rl"
+	case 16:
+#line 1280 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(start_array(parser)); }
 	break;
-	case 28:
-//#line 2121 "upb/json/parser.rl"
+	case 17:
+#line 1284 "upb/json/parser.rl"
 	{ end_array(parser); }
 	break;
-	case 29:
-//#line 2126 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(start_number(parser, p)); }
+	case 18:
+#line 1289 "upb/json/parser.rl"
+	{ start_number(parser, p); }
 	break;
-	case 30:
-//#line 2127 "upb/json/parser.rl"
+	case 19:
+#line 1290 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_number(parser, p)); }
 	break;
-	case 31:
-//#line 2129 "upb/json/parser.rl"
+	case 20:
+#line 1292 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(start_stringval(parser)); }
 	break;
-	case 32:
-//#line 2130 "upb/json/parser.rl"
+	case 21:
+#line 1293 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_stringval(parser)); }
 	break;
-	case 33:
-//#line 2132 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_bool(parser, true)); }
+	case 22:
+#line 1295 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(parser_putbool(parser, true)); }
 	break;
-	case 34:
-//#line 2134 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_bool(parser, false)); }
+	case 23:
+#line 1297 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(parser_putbool(parser, false)); }
 	break;
-	case 35:
-//#line 2136 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_null(parser)); }
+	case 24:
+#line 1299 "upb/json/parser.rl"
+	{ /* null value */ }
 	break;
-	case 36:
-//#line 2138 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(start_subobject_full(parser)); }
+	case 25:
+#line 1301 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(start_subobject(parser)); }
 	break;
-	case 37:
-//#line 2139 "upb/json/parser.rl"
-	{ end_subobject_full(parser); }
+	case 26:
+#line 1302 "upb/json/parser.rl"
+	{ end_subobject(parser); }
 	break;
-	case 38:
-//#line 2144 "upb/json/parser.rl"
+	case 27:
+#line 1307 "upb/json/parser.rl"
 	{ p--; {cs = stack[--top]; goto _again;} }
 	break;
-//#line 2524 "upb/json/parser.c"
+#line 1579 "upb/json/parser.c"
 		}
 	}
 
@@ -15076,49 +13894,10 @@
 	if ( ++p != pe )
 		goto _resume;
 	_test_eof: {}
-	if ( p == eof )
-	{
-	const char *__acts = _json_actions + _json_eof_actions[cs];
-	unsigned int __nacts = (unsigned int) *__acts++;
-	while ( __nacts-- > 0 ) {
-		switch ( *__acts++ ) {
-	case 0:
-//#line 2019 "upb/json/parser.rl"
-	{ p--; {cs = stack[--top]; goto _again;} }
-	break;
-	case 26:
-//#line 2111 "upb/json/parser.rl"
-	{ end_object(parser); }
-	break;
-	case 30:
-//#line 2127 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_number(parser, p)); }
-	break;
-	case 33:
-//#line 2132 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_bool(parser, true)); }
-	break;
-	case 34:
-//#line 2134 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_bool(parser, false)); }
-	break;
-	case 35:
-//#line 2136 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_null(parser)); }
-	break;
-	case 37:
-//#line 2139 "upb/json/parser.rl"
-	{ end_subobject_full(parser); }
-	break;
-//#line 2568 "upb/json/parser.c"
-		}
-	}
-	}
-
 	_out: {}
 	}
 
-//#line 2172 "upb/json/parser.rl"
+#line 1334 "upb/json/parser.rl"
 
   if (p != pe) {
     upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p);
@@ -15136,24 +13915,16 @@
 }
 
 bool end(void *closure, const void *hd) {
-  upb_json_parser *parser = closure;
+  UPB_UNUSED(closure);
+  UPB_UNUSED(hd);
 
   /* Prevent compile warning on unused static constants. */
   UPB_UNUSED(json_start);
-  UPB_UNUSED(json_en_duration_machine);
   UPB_UNUSED(json_en_number_machine);
   UPB_UNUSED(json_en_string_machine);
-  UPB_UNUSED(json_en_timestamp_machine);
   UPB_UNUSED(json_en_value_machine);
   UPB_UNUSED(json_en_main);
-
-  parse(parser, hd, &eof_ch, 0, NULL);
-
-  return parser->current_state >= 
-//#line 2608 "upb/json/parser.c"
-105
-//#line 2202 "upb/json/parser.rl"
-;
+  return true;
 }
 
 static void json_parser_reset(upb_json_parser *p) {
@@ -15164,17 +13935,16 @@
   p->top->f = NULL;
   p->top->is_map = false;
   p->top->is_mapentry = false;
-  p->top->is_unknown_field = false;
 
   /* Emit Ragel initialization of the parser. */
   
-//#line 2626 "upb/json/parser.c"
+#line 1633 "upb/json/parser.c"
 	{
 	cs = json_start;
 	top = 0;
 	}
 
-//#line 2217 "upb/json/parser.rl"
+#line 1374 "upb/json/parser.rl"
   p->current_state = cs;
   p->parser_top = top;
   accumulate_clear(p);
@@ -15261,8 +14031,7 @@
 
 upb_json_parser *upb_json_parser_create(upb_env *env,
                                         const upb_json_parsermethod *method,
-                                        upb_sink *output,
-                                        bool ignore_json_unknown) {
+                                        upb_sink *output) {
 #ifndef NDEBUG
   const size_t size_before = upb_env_bytesallocated(env);
 #endif
@@ -15281,8 +14050,6 @@
   p->top->m = upb_handlers_msgdef(output->handlers);
   set_name_table(p, p->top);
 
-  p->ignore_json_unknown = ignore_json_unknown;
-
   /* If this fails, uncomment and increase the value in parser.h. */
   /* fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before); */
   UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(env) - size_before <=
@@ -15327,7 +14094,6 @@
 
 #include <string.h>
 #include <stdint.h>
-#include <time.h>
 
 struct upb_json_printer {
   upb_sink input_;
@@ -15348,12 +14114,6 @@
    * repeated fields and messages (maps), and the worst case is a
    * message->repeated field->submessage->repeated field->... nesting. */
   bool first_elem_[UPB_MAX_HANDLER_DEPTH * 2];
-
-  /* To print timestamp, printer needs to cache its seconds and nanos values
-   * and convert them when ending timestamp message. See comments of
-   * printer_sethandlers_timestamp for more detail. */
-  int64_t seconds;
-  int32_t nanos;
 };
 
 /* StringPiece; a pointer plus a length. */
@@ -16012,369 +14772,6 @@
   upb_handlerattr_uninit(&empty_attr);
 }
 
-static bool putseconds(void *closure, const void *handler_data,
-                       int64_t seconds) {
-  upb_json_printer *p = closure;
-  p->seconds = seconds;
-  UPB_UNUSED(handler_data);
-  return true;
-}
-
-static bool putnanos(void *closure, const void *handler_data,
-                     int32_t nanos) {
-  upb_json_printer *p = closure;
-  p->nanos = nanos;
-  UPB_UNUSED(handler_data);
-  return true;
-}
-
-static void *scalar_startstr_nokey(void *closure, const void *handler_data,
-                                   size_t size_hint) {
-  upb_json_printer *p = closure;
-  UPB_UNUSED(handler_data);
-  UPB_UNUSED(size_hint);
-  print_data(p, "\"", 1);
-  return p;
-}
-
-static size_t putstr_nokey(void *closure, const void *handler_data,
-                           const char *str, size_t len,
-                           const upb_bufhandle *handle) {
-  upb_json_printer *p = closure;
-  UPB_UNUSED(handler_data);
-  UPB_UNUSED(handle);
-  print_data(p, "\"", 1);
-  putstring(p, str, len);
-  print_data(p, "\"", 1);
-  return len + 2;
-}
-
-static void *startseq_nokey(void *closure, const void *handler_data) {
-  upb_json_printer *p = closure;
-  UPB_UNUSED(handler_data);
-  p->depth_++;
-  p->first_elem_[p->depth_] = true;
-  print_data(p, "[", 1);
-  return closure;
-}
-
-static void *startmap_nokey(void *closure, const void *handler_data) {
-  upb_json_printer *p = closure;
-  UPB_UNUSED(handler_data);
-  p->depth_++;
-  p->first_elem_[p->depth_] = true;
-  print_data(p, "{", 1);
-  return closure;
-}
-
-static bool putnull(void *closure, const void *handler_data,
-                    int32_t null) {
-  upb_json_printer *p = closure;
-  print_data(p, "null", 4);
-  UPB_UNUSED(handler_data);
-  UPB_UNUSED(null);
-  return true;
-}
-
-static bool printer_startdurationmsg(void *closure, const void *handler_data) {
-  upb_json_printer *p = closure;
-  UPB_UNUSED(handler_data);
-  if (p->depth_ == 0) {
-    upb_bytessink_start(p->output_, 0, &p->subc_);
-  }
-  return true;
-}
-
-#define UPB_DURATION_MAX_JSON_LEN 23
-#define UPB_DURATION_MAX_NANO_LEN 9
-
-static bool printer_enddurationmsg(void *closure, const void *handler_data,
-                                   upb_status *s) {
-  upb_json_printer *p = closure;
-  char buffer[UPB_DURATION_MAX_JSON_LEN];
-  size_t base_len;
-  size_t curr;
-  size_t i;
-
-  memset(buffer, 0, UPB_DURATION_MAX_JSON_LEN);
-
-  if (p->seconds < -315576000000) {
-    upb_status_seterrf(s, "error parsing duration: "
-                          "minimum acceptable value is "
-                          "-315576000000");
-    return false;
-  }
-
-  if (p->seconds > 315576000000) {
-    upb_status_seterrf(s, "error serializing duration: "
-                          "maximum acceptable value is "
-                          "315576000000");
-    return false;
-  }
-
-  _upb_snprintf(buffer, sizeof(buffer), "%ld", (long)p->seconds);
-  base_len = strlen(buffer);
-
-  if (p->nanos != 0) {
-    char nanos_buffer[UPB_DURATION_MAX_NANO_LEN + 3];
-    _upb_snprintf(nanos_buffer, sizeof(nanos_buffer), "%.9f",
-                  p->nanos / 1000000000.0);
-    /* Remove trailing 0. */
-    for (i = UPB_DURATION_MAX_NANO_LEN + 2;
-         nanos_buffer[i] == '0'; i--) {
-      nanos_buffer[i] = 0;
-    }
-    strcpy(buffer + base_len, nanos_buffer + 1);
-  }
-
-  curr = strlen(buffer);
-  strcpy(buffer + curr, "s");
-
-  p->seconds = 0;
-  p->nanos = 0;
-
-  print_data(p, "\"", 1);
-  print_data(p, buffer, strlen(buffer));
-  print_data(p, "\"", 1);
-
-  if (p->depth_ == 0) {
-    upb_bytessink_end(p->output_);
-  }
-
-  UPB_UNUSED(handler_data);
-  return true;
-}
-
-static bool printer_starttimestampmsg(void *closure, const void *handler_data) {
-  upb_json_printer *p = closure;
-  UPB_UNUSED(handler_data);
-  if (p->depth_ == 0) {
-    upb_bytessink_start(p->output_, 0, &p->subc_);
-  }
-  return true;
-}
-
-#define UPB_TIMESTAMP_MAX_JSON_LEN 31
-#define UPB_TIMESTAMP_BEFORE_NANO_LEN 19
-#define UPB_TIMESTAMP_MAX_NANO_LEN 9
-
-static bool printer_endtimestampmsg(void *closure, const void *handler_data,
-                                    upb_status *s) {
-  upb_json_printer *p = closure;
-  char buffer[UPB_TIMESTAMP_MAX_JSON_LEN];
-  time_t time = p->seconds;
-  size_t curr;
-  size_t i;
-  size_t year_length =
-      strftime(buffer, UPB_TIMESTAMP_MAX_JSON_LEN, "%Y", gmtime(&time));
-
-  if (p->seconds < -62135596800) {
-    upb_status_seterrf(s, "error parsing timestamp: "
-                          "minimum acceptable value is "
-                          "0001-01-01T00:00:00Z");
-    return false;
-  }
-
-  if (p->seconds > 253402300799) {
-    upb_status_seterrf(s, "error parsing timestamp: "
-                          "maximum acceptable value is "
-                          "9999-12-31T23:59:59Z");
-    return false;
-  }
-
-  /* strftime doesn't guarantee 4 digits for year. Prepend 0 by ourselves. */
-  for (i = 0; i < 4 - year_length; i++) {
-    buffer[i] = '0';
-  }
-
-  strftime(buffer + (4 - year_length), UPB_TIMESTAMP_MAX_JSON_LEN,
-           "%Y-%m-%dT%H:%M:%S", gmtime(&time));
-  if (p->nanos != 0) {
-    char nanos_buffer[UPB_TIMESTAMP_MAX_NANO_LEN + 3];
-    _upb_snprintf(nanos_buffer, sizeof(nanos_buffer), "%.9f",
-                  p->nanos / 1000000000.0);
-    /* Remove trailing 0. */
-    for (i = UPB_TIMESTAMP_MAX_NANO_LEN + 2;
-         nanos_buffer[i] == '0'; i--) {
-      nanos_buffer[i] = 0;
-    }
-    strcpy(buffer + UPB_TIMESTAMP_BEFORE_NANO_LEN, nanos_buffer + 1);
-  }
-
-  curr = strlen(buffer);
-  strcpy(buffer + curr, "Z");
-
-  p->seconds = 0;
-  p->nanos = 0;
-
-  print_data(p, "\"", 1);
-  print_data(p, buffer, strlen(buffer));
-  print_data(p, "\"", 1);
-
-  if (p->depth_ == 0) {
-    upb_bytessink_end(p->output_);
-  }
-
-  UPB_UNUSED(handler_data);
-  UPB_UNUSED(s);
-  return true;
-}
-
-static bool printer_startmsg_noframe(void *closure, const void *handler_data) {
-  upb_json_printer *p = closure;
-  UPB_UNUSED(handler_data);
-  if (p->depth_ == 0) {
-    upb_bytessink_start(p->output_, 0, &p->subc_);
-  }
-  return true;
-}
-
-static bool printer_endmsg_noframe(
-    void *closure, const void *handler_data, upb_status *s) {
-  upb_json_printer *p = closure;
-  UPB_UNUSED(handler_data);
-  UPB_UNUSED(s);
-  if (p->depth_ == 0) {
-    upb_bytessink_end(p->output_);
-  }
-  return true;
-}
-
-/* Set up handlers for a duration submessage. */
-void printer_sethandlers_duration(const void *closure, upb_handlers *h) {
-  const upb_msgdef *md = upb_handlers_msgdef(h);
-
-  const upb_fielddef* seconds_field =
-      upb_msgdef_itof(md, UPB_DURATION_SECONDS);
-  const upb_fielddef* nanos_field =
-      upb_msgdef_itof(md, UPB_DURATION_NANOS);
-
-  upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
-
-  upb_handlers_setstartmsg(h, printer_startdurationmsg, &empty_attr);
-  upb_handlers_setint64(h, seconds_field, putseconds, &empty_attr);
-  upb_handlers_setint32(h, nanos_field, putnanos, &empty_attr);
-  upb_handlers_setendmsg(h, printer_enddurationmsg, &empty_attr);
-
-  UPB_UNUSED(closure);
-}
-
-/* Set up handlers for a timestamp submessage. Instead of printing fields
- * separately, the json representation of timestamp follows RFC 3339 */
-void printer_sethandlers_timestamp(const void *closure, upb_handlers *h) {
-  const upb_msgdef *md = upb_handlers_msgdef(h);
-
-  const upb_fielddef* seconds_field =
-      upb_msgdef_itof(md, UPB_TIMESTAMP_SECONDS);
-  const upb_fielddef* nanos_field =
-      upb_msgdef_itof(md, UPB_TIMESTAMP_NANOS);
-
-  upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
-
-  upb_handlers_setstartmsg(h, printer_starttimestampmsg, &empty_attr);
-  upb_handlers_setint64(h, seconds_field, putseconds, &empty_attr);
-  upb_handlers_setint32(h, nanos_field, putnanos, &empty_attr);
-  upb_handlers_setendmsg(h, printer_endtimestampmsg, &empty_attr);
-
-  UPB_UNUSED(closure);
-}
-
-void printer_sethandlers_value(const void *closure, upb_handlers *h) {
-  const upb_msgdef *md = upb_handlers_msgdef(h);
-  upb_msg_field_iter i;
-
-  upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
-
-  upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr);
-  upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr);
-
-  upb_msg_field_begin(&i, md);
-  for(; !upb_msg_field_done(&i); upb_msg_field_next(&i)) {
-    const upb_fielddef *f = upb_msg_iter_field(&i);
-
-    switch (upb_fielddef_type(f)) {
-      case UPB_TYPE_ENUM:
-        upb_handlers_setint32(h, f, putnull, &empty_attr);
-        break;
-      case UPB_TYPE_DOUBLE:
-        upb_handlers_setdouble(h, f, putdouble, &empty_attr);
-        break;
-      case UPB_TYPE_STRING:
-        upb_handlers_setstartstr(h, f, scalar_startstr_nokey, &empty_attr);
-        upb_handlers_setstring(h, f, scalar_str, &empty_attr);
-        upb_handlers_setendstr(h, f, scalar_endstr, &empty_attr);
-        break;
-      case UPB_TYPE_BOOL:
-        upb_handlers_setbool(h, f, putbool, &empty_attr);
-        break;
-      case UPB_TYPE_MESSAGE:
-        break;
-      default:
-        UPB_ASSERT(false);
-        break;
-    }
-  }
-
-  UPB_UNUSED(closure);
-}
-
-#define WRAPPER_SETHANDLERS(wrapper, type, putmethod)                      \
-void printer_sethandlers_##wrapper(const void *closure, upb_handlers *h) { \
-  const upb_msgdef *md = upb_handlers_msgdef(h);                           \
-  const upb_fielddef* f = upb_msgdef_itof(md, 1);                          \
-  upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;                \
-  upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr);      \
-  upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr);          \
-  upb_handlers_set##type(h, f, putmethod, &empty_attr);                    \
-  UPB_UNUSED(closure);                                                     \
-}
-
-WRAPPER_SETHANDLERS(doublevalue, double, putdouble)
-WRAPPER_SETHANDLERS(floatvalue,  float,  putfloat)
-WRAPPER_SETHANDLERS(int64value,  int64,  putint64_t)
-WRAPPER_SETHANDLERS(uint64value, uint64, putuint64_t)
-WRAPPER_SETHANDLERS(int32value,  int32,  putint32_t)
-WRAPPER_SETHANDLERS(uint32value, uint32, putuint32_t)
-WRAPPER_SETHANDLERS(boolvalue,   bool,   putbool)
-WRAPPER_SETHANDLERS(stringvalue, string, putstr_nokey)
-WRAPPER_SETHANDLERS(bytesvalue,  string, putbytes)
-
-#undef WRAPPER_SETHANDLERS
-
-void printer_sethandlers_listvalue(const void *closure, upb_handlers *h) {
-  const upb_msgdef *md = upb_handlers_msgdef(h);
-  const upb_fielddef* f = upb_msgdef_itof(md, 1);
-
-  upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
-
-  upb_handlers_setstartseq(h, f, startseq_nokey, &empty_attr);
-  upb_handlers_setendseq(h, f, endseq, &empty_attr);
-
-  upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr);
-  upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr);
-
-  upb_handlers_setstartsubmsg(h, f, repeated_startsubmsg, &empty_attr);
-
-  UPB_UNUSED(closure);
-}
-
-void printer_sethandlers_structvalue(const void *closure, upb_handlers *h) {
-  const upb_msgdef *md = upb_handlers_msgdef(h);
-  const upb_fielddef* f = upb_msgdef_itof(md, 1);
-
-  upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
-
-  upb_handlers_setstartseq(h, f, startmap_nokey, &empty_attr);
-  upb_handlers_setendseq(h, f, endmap, &empty_attr);
-
-  upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr);
-  upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr);
-
-  upb_handlers_setstartsubmsg(h, f, repeated_startsubmsg, &empty_attr);
-
-  UPB_UNUSED(closure);
-}
-
 void printer_sethandlers(const void *closure, upb_handlers *h) {
   const upb_msgdef *md = upb_handlers_msgdef(h);
   bool is_mapentry = upb_msgdef_mapentry(md);
@@ -16390,42 +14787,6 @@
     return;
   }
 
-  switch (upb_msgdef_wellknowntype(md)) {
-    case UPB_WELLKNOWN_UNSPECIFIED:
-      break;
-    case UPB_WELLKNOWN_DURATION:
-      printer_sethandlers_duration(closure, h);
-      return;
-    case UPB_WELLKNOWN_TIMESTAMP:
-      printer_sethandlers_timestamp(closure, h);
-      return;
-    case UPB_WELLKNOWN_VALUE:
-      printer_sethandlers_value(closure, h);
-      return;
-    case UPB_WELLKNOWN_LISTVALUE:
-      printer_sethandlers_listvalue(closure, h);
-      return;
-    case UPB_WELLKNOWN_STRUCT:
-      printer_sethandlers_structvalue(closure, h);
-      return;
-#define WRAPPER(wellknowntype, name)        \
-  case wellknowntype:                       \
-    printer_sethandlers_##name(closure, h); \
-    return;                                 \
-
-    WRAPPER(UPB_WELLKNOWN_DOUBLEVALUE, doublevalue);
-    WRAPPER(UPB_WELLKNOWN_FLOATVALUE, floatvalue);
-    WRAPPER(UPB_WELLKNOWN_INT64VALUE, int64value);
-    WRAPPER(UPB_WELLKNOWN_UINT64VALUE, uint64value);
-    WRAPPER(UPB_WELLKNOWN_INT32VALUE, int32value);
-    WRAPPER(UPB_WELLKNOWN_UINT32VALUE, uint32value);
-    WRAPPER(UPB_WELLKNOWN_BOOLVALUE, boolvalue);
-    WRAPPER(UPB_WELLKNOWN_STRINGVALUE, stringvalue);
-    WRAPPER(UPB_WELLKNOWN_BYTESVALUE, bytesvalue);
-
-#undef WRAPPER
-  }
-
   upb_handlers_setstartmsg(h, printer_startmsg, &empty_attr);
   upb_handlers_setendmsg(h, printer_endmsg, &empty_attr);
 
@@ -16533,8 +14894,6 @@
   p->output_ = output;
   json_printer_reset(p);
   upb_sink_reset(&p->input_, h, p);
-  p->seconds = 0;
-  p->nanos = 0;
 
   /* If this fails, increase the value in printer.h. */
   UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(e) - size_before <=
@@ -16552,8 +14911,3 @@
   return upb_handlers_newfrozen(
       md, owner, printer_sethandlers, &preserve_fieldnames);
 }
-
-#undef UPB_SIZE
-#undef UPB_FIELD_AT
-#undef UPB_READ_ONEOF
-#undef UPB_WRITE_ONEOF
diff --git a/ruby/ext/google/protobuf_c/upb.h b/ruby/ext/google/protobuf_c/upb.h
index 0670a81..f441c89 100644
--- a/ruby/ext/google/protobuf_c/upb.h
+++ b/ruby/ext/google/protobuf_c/upb.h
@@ -1,116 +1,4 @@
 // Amalgamated source file
-
-// php.h intentionally defined NDEBUG. We have to define this macro in order to
-// be used together with php.h
-#ifndef NDEBUG
-#define NDEBUG
-#endif
-
-#if UINTPTR_MAX == 0xffffffff
-#define UPB_SIZE(size32, size64) size32
-#else
-#define UPB_SIZE(size32, size64) size64
-#endif
-
-#define UPB_FIELD_AT(msg, fieldtype, offset) \
-  *(fieldtype*)((const char*)(msg) + offset)
-
-#define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
-  UPB_FIELD_AT(msg, int, case_offset) == case_val                              \
-      ? UPB_FIELD_AT(msg, fieldtype, offset)                                   \
-      : default
-
-#define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
-  UPB_FIELD_AT(msg, int, case_offset) = case_val;                             \
-  UPB_FIELD_AT(msg, fieldtype, offset) = value;
-/*
-** upb::Message is a representation for protobuf messages.
-**
-** However it differs from other common representations like
-** google::protobuf::Message in one key way: it does not prescribe any
-** ownership between messages and submessages, and it relies on the
-** client to ensure that each submessage/array/map outlives its parent.
-**
-** All messages, arrays, and maps live in an Arena.  If the entire message
-** tree is in the same arena, ensuring proper lifetimes is simple.  However
-** the client can mix arenas as long as they ensure that there are no
-** dangling pointers.
-**
-** A client can access a upb::Message without knowing anything about
-** ownership semantics, but to create or mutate a message a user needs
-** to implement the memory management themselves.
-**
-** TODO: UTF-8 checking?
-**/
-
-#ifndef UPB_MSG_H_
-#define UPB_MSG_H_
-
-/*
-** Defs are upb's internal representation of the constructs that can appear
-** in a .proto file:
-**
-** - upb::MessageDef (upb_msgdef): describes a "message" construct.
-** - upb::FieldDef (upb_fielddef): describes a message field.
-** - upb::FileDef (upb_filedef): describes a .proto file and its defs.
-** - upb::EnumDef (upb_enumdef): describes an enum.
-** - upb::OneofDef (upb_oneofdef): describes a oneof.
-** - upb::Def (upb_def): base class of all the others.
-**
-** TODO: definitions of services.
-**
-** Like upb_refcounted objects, defs are mutable only until frozen, and are
-** only thread-safe once frozen.
-**
-** This is a mixed C/C++ interface that offers a full API to both languages.
-** See the top-level README for more information.
-*/
-
-#ifndef UPB_DEF_H_
-#define UPB_DEF_H_
-
-/*
-** upb::RefCounted (upb_refcounted)
-**
-** A refcounting scheme that supports circular refs.  It accomplishes this by
-** partitioning the set of objects into groups such that no cycle spans groups;
-** we can then reference-count the group as a whole and ignore refs within the
-** group.  When objects are mutable, these groups are computed very
-** conservatively; we group any objects that have ever had a link between them.
-** When objects are frozen, we compute strongly-connected components which
-** allows us to be precise and only group objects that are actually cyclic.
-**
-** This is a mixed C/C++ interface that offers a full API to both languages.
-** See the top-level README for more information.
-*/
-
-#ifndef UPB_REFCOUNTED_H_
-#define UPB_REFCOUNTED_H_
-
-/*
-** upb_table
-**
-** This header is INTERNAL-ONLY!  Its interfaces are not public or stable!
-** This file defines very fast int->upb_value (inttable) and string->upb_value
-** (strtable) hash tables.
-**
-** The table uses chained scatter with Brent's variation (inspired by the Lua
-** implementation of hash tables).  The hash function for strings is Austin
-** Appleby's "MurmurHash."
-**
-** The inttable uses uintptr_t as its key, which guarantees it can be used to
-** store pointers or integers of at least 32 bits (upb isn't really useful on
-** systems where sizeof(void*) < 4).
-**
-** The table must be homogenous (all values of the same type).  In debug
-** mode, we check this on insert and lookup.
-*/
-
-#ifndef UPB_TABLE_H_
-#define UPB_TABLE_H_
-
-#include <stdint.h>
-#include <string.h>
 /*
 ** This file contains shared definitions that are widely used across upb.
 **
@@ -849,6 +737,106 @@
 
 
 #endif  /* UPB_H_ */
+/*
+** upb_decode: parsing into a upb_msg using a upb_msglayout.
+*/
+
+#ifndef UPB_DECODE_H_
+#define UPB_DECODE_H_
+
+/*
+** upb::Message is a representation for protobuf messages.
+**
+** However it differs from other common representations like
+** google::protobuf::Message in one key way: it does not prescribe any
+** ownership between messages and submessages, and it relies on the
+** client to delete each message/submessage/array/map at the appropriate
+** time.
+**
+** A client can access a upb::Message without knowing anything about
+** ownership semantics, but to create or mutate a message a user needs
+** to implement the memory management themselves.
+**
+** Currently all messages, arrays, and maps store a upb_alloc* internally.
+** Mutating operations use this when they require dynamically-allocated
+** memory.  We could potentially eliminate this size overhead later by
+** letting the user flip a bit on the factory that prevents this from
+** being stored.  The user would then need to use separate functions where
+** the upb_alloc* is passed explicitly.  However for handlers to populate
+** such structures, they would need a place to store this upb_alloc* during
+** parsing; upb_handlers don't currently have a good way to accommodate this.
+**
+** TODO: UTF-8 checking?
+**/
+
+#ifndef UPB_MSG_H_
+#define UPB_MSG_H_
+
+/*
+** Defs are upb's internal representation of the constructs that can appear
+** in a .proto file:
+**
+** - upb::MessageDef (upb_msgdef): describes a "message" construct.
+** - upb::FieldDef (upb_fielddef): describes a message field.
+** - upb::FileDef (upb_filedef): describes a .proto file and its defs.
+** - upb::EnumDef (upb_enumdef): describes an enum.
+** - upb::OneofDef (upb_oneofdef): describes a oneof.
+** - upb::Def (upb_def): base class of all the others.
+**
+** TODO: definitions of services.
+**
+** Like upb_refcounted objects, defs are mutable only until frozen, and are
+** only thread-safe once frozen.
+**
+** This is a mixed C/C++ interface that offers a full API to both languages.
+** See the top-level README for more information.
+*/
+
+#ifndef UPB_DEF_H_
+#define UPB_DEF_H_
+
+/*
+** upb::RefCounted (upb_refcounted)
+**
+** A refcounting scheme that supports circular refs.  It accomplishes this by
+** partitioning the set of objects into groups such that no cycle spans groups;
+** we can then reference-count the group as a whole and ignore refs within the
+** group.  When objects are mutable, these groups are computed very
+** conservatively; we group any objects that have ever had a link between them.
+** When objects are frozen, we compute strongly-connected components which
+** allows us to be precise and only group objects that are actually cyclic.
+**
+** This is a mixed C/C++ interface that offers a full API to both languages.
+** See the top-level README for more information.
+*/
+
+#ifndef UPB_REFCOUNTED_H_
+#define UPB_REFCOUNTED_H_
+
+/*
+** upb_table
+**
+** This header is INTERNAL-ONLY!  Its interfaces are not public or stable!
+** This file defines very fast int->upb_value (inttable) and string->upb_value
+** (strtable) hash tables.
+**
+** The table uses chained scatter with Brent's variation (inspired by the Lua
+** implementation of hash tables).  The hash function for strings is Austin
+** Appleby's "MurmurHash."
+**
+** The inttable uses uintptr_t as its key, which guarantees it can be used to
+** store pointers or integers of at least 32 bits (upb isn't really useful on
+** systems where sizeof(void*) < 4).
+**
+** The table must be homogenous (all values of the same type).  In debug
+** mode, we check this on insert and lookup.
+*/
+
+#ifndef UPB_TABLE_H_
+#define UPB_TABLE_H_
+
+#include <stdint.h>
+#include <string.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -2007,34 +1995,6 @@
   UPB_SYNTAX_PROTO3 = 3
 } upb_syntax_t;
 
-/* All the different kind of well known type messages. For simplicity of check,
- * number wrappers and string wrappers are grouped together. Make sure the
- * order and merber of these groups are not changed.
- */
-typedef enum {
-  UPB_WELLKNOWN_UNSPECIFIED,
-  UPB_WELLKNOWN_DURATION,
-  UPB_WELLKNOWN_TIMESTAMP,
-  /* number wrappers */
-  UPB_WELLKNOWN_DOUBLEVALUE,
-  UPB_WELLKNOWN_FLOATVALUE,
-  UPB_WELLKNOWN_INT64VALUE,
-  UPB_WELLKNOWN_UINT64VALUE,
-  UPB_WELLKNOWN_INT32VALUE,
-  UPB_WELLKNOWN_UINT32VALUE,
-  /* string wrappers */
-  UPB_WELLKNOWN_STRINGVALUE,
-  UPB_WELLKNOWN_BYTESVALUE,
-  UPB_WELLKNOWN_BOOLVALUE,
-  UPB_WELLKNOWN_VALUE,
-  UPB_WELLKNOWN_LISTVALUE,
-  UPB_WELLKNOWN_STRUCT
-} upb_wellknowntype_t;
-
-
-/* Maps descriptor type -> upb field type.  */
-extern const uint8_t upb_desctype_to_fieldtype[];
-
 /* Maximum field number allowed for FieldDefs.  This is an inherent limit of the
  * protobuf wire format. */
 #define UPB_MAX_FIELDNUMBER ((1 << 29) - 1)
@@ -2416,14 +2376,6 @@
 #define UPB_MAPENTRY_KEY   1
 #define UPB_MAPENTRY_VALUE 2
 
-/* Well-known field tag numbers for timestamp messages. */
-#define UPB_DURATION_SECONDS 1
-#define UPB_DURATION_NANOS 2
-
-/* Well-known field tag numbers for duration messages. */
-#define UPB_TIMESTAMP_SECONDS 1
-#define UPB_TIMESTAMP_NANOS 2
-
 #ifdef __cplusplus
 
 /* Structure that describes a single .proto message type.
@@ -2538,13 +2490,6 @@
   void setmapentry(bool map_entry);
   bool mapentry() const;
 
-  /* Return the type of well known type message. UPB_WELLKNOWN_UNSPECIFIED for
-   * non-well-known message. */
-  upb_wellknowntype_t wellknowntype() const;
-
-  /* Whether is a number wrapper. */
-  bool isnumberwrapper() const;
-
   /* Iteration over fields.  The order is undefined. */
   class field_iterator
       : public std::iterator<std::forward_iterator_tag, FieldDef*> {
@@ -2686,8 +2631,6 @@
 bool upb_msgdef_setfullname(upb_msgdef *m, const char *fullname, upb_status *s);
 void upb_msgdef_setmapentry(upb_msgdef *m, bool map_entry);
 bool upb_msgdef_mapentry(const upb_msgdef *m);
-upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m);
-bool upb_msgdef_isnumberwrapper(const upb_msgdef *m);
 bool upb_msgdef_setsyntax(upb_msgdef *m, upb_syntax_t syntax);
 
 /* Field lookup in a couple of different variations:
@@ -3627,12 +3570,6 @@
 inline bool MessageDef::mapentry() const {
   return upb_msgdef_mapentry(this);
 }
-inline upb_wellknowntype_t MessageDef::wellknowntype() const {
-  return upb_msgdef_wellknowntype(this);
-}
-inline bool MessageDef::isnumberwrapper() const {
-  return upb_msgdef_isnumberwrapper(this);
-}
 inline MessageDef::field_iterator MessageDef::field_begin() {
   return field_iterator(this);
 }
@@ -4760,34 +4697,6 @@
 uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f);
 uint32_t upb_handlers_selectorcount(const upb_fielddef *f);
 
-
-/** Message handlers ******************************************************************/
-
-/* These are the handlers used internally by upb_msgfactory_getmergehandlers().
- * They write scalar data to a known offset from the message pointer.
- *
- * These would be trivial for anyone to implement themselves, but it's better
- * to use these because some JITs will recognize and specialize these instead
- * of actually calling the function. */
-
-/* Sets a handler for the given primitive field that will write the data at the
- * given offset.  If hasbit > 0, also sets a hasbit at the given bit offset
- * (addressing each byte low to high). */
-bool upb_msg_setscalarhandler(upb_handlers *h,
-                              const upb_fielddef *f,
-                              size_t offset,
-                              int32_t hasbit);
-
-/* If the given handler is a msghandlers_primitive field, returns true and sets
- * *type, *offset and *hasbit.  Otherwise returns false. */
-bool upb_msg_getscalarhandlerdata(const upb_handlers *h,
-                                  upb_selector_t s,
-                                  upb_fieldtype_t *type,
-                                  size_t *offset,
-                                  int32_t *hasbit);
-
-
-
 UPB_END_EXTERN_C
 
 /*
@@ -6472,14 +6381,21 @@
 class Array;
 class Map;
 class MapIterator;
+class MessageFactory;
 class MessageLayout;
+class Visitor;
+class VisitorPlan;
 }
 
 #endif
 
+UPB_DECLARE_TYPE(upb::MessageFactory, upb_msgfactory)
+UPB_DECLARE_TYPE(upb::MessageLayout, upb_msglayout)
 UPB_DECLARE_TYPE(upb::Array, upb_array)
 UPB_DECLARE_TYPE(upb::Map, upb_map)
 UPB_DECLARE_TYPE(upb::MapIterator, upb_mapiter)
+UPB_DECLARE_TYPE(upb::Visitor, upb_visitor)
+UPB_DECLARE_TYPE(upb::VisitorPlan, upb_visitorplan)
 
 /* TODO(haberman): C++ accessors */
 
@@ -6490,28 +6406,53 @@
 
 /** upb_msglayout *************************************************************/
 
-/* upb_msglayout represents the memory layout of a given upb_msgdef.  The
- * members are public so generated code can initialize them, but users MUST NOT
- * read or write any of its members. */
+/* upb_msglayout represents the memory layout of a given upb_msgdef.  You get
+ * instances of this from a upb_msgfactory, and the factory always owns the
+ * msglayout. */
 
-typedef struct {
-  uint32_t number;
-  uint16_t offset;
-  int16_t presence;      /* If >0, hasbit_index+1.  If <0, oneof_index+1. */
-  uint16_t submsg_index;  /* undefined if descriptortype != MESSAGE or GROUP. */
-  uint8_t descriptortype;
-  uint8_t label;
-} upb_msglayout_field;
 
-typedef struct upb_msglayout {
-  const struct upb_msglayout *const* submsgs;
-  const upb_msglayout_field *fields;
-  /* Must be aligned to sizeof(void*).  Doesn't include internal members like
-   * unknown fields, extension dict, pointer to msglayout, etc. */
-  uint16_t size;
-  uint16_t field_count;
-  bool extendable;
-} upb_msglayout;
+/** upb_visitor ***************************************************************/
+
+/* upb_visitor will visit all the fields of a message and its submessages.  It
+ * uses a upb_visitorplan which you can obtain from a upb_msgfactory. */
+
+upb_visitor *upb_visitor_create(upb_env *e, const upb_visitorplan *vp,
+                                upb_sink *output);
+bool upb_visitor_visitmsg(upb_visitor *v, const upb_msg *msg);
+
+
+/** upb_msgfactory ************************************************************/
+
+/* A upb_msgfactory contains a cache of upb_msglayout, upb_handlers, and
+ * upb_visitorplan objects.  These are the objects necessary to represent,
+ * populate, and and visit upb_msg objects.
+ *
+ * These caches are all populated by upb_msgdef, and lazily created on demand.
+ */
+
+/* Creates and destroys a msgfactory, respectively.  The messages for this
+ * msgfactory must come from |symtab| (which should outlive the msgfactory). */
+upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab);
+void upb_msgfactory_free(upb_msgfactory *f);
+
+const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f);
+
+/* The functions to get cached objects, lazily creating them on demand.  These
+ * all require:
+ *
+ * - m is in upb_msgfactory_symtab(f)
+ * - upb_msgdef_mapentry(m) == false (since map messages can't have layouts).
+ *
+ * The returned objects will live for as long as the msgfactory does.
+ *
+ * TODO(haberman): consider making this thread-safe and take a const
+ * upb_msgfactory. */
+const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
+                                              const upb_msgdef *m);
+const upb_handlers *upb_msgfactory_getmergehandlers(upb_msgfactory *f,
+                                                    const upb_msgdef *m);
+const upb_visitorplan *upb_msgfactory_getvisitorplan(upb_msgfactory *f,
+                                                     const upb_handlers *h);
 
 
 /** upb_stringview ************************************************************/
@@ -6587,16 +6528,52 @@
 /** upb_msg *******************************************************************/
 
 /* A upb_msg represents a protobuf message.  It always corresponds to a specific
- * upb_msglayout, which describes how it is laid out in memory.  */
+ * upb_msglayout, which describes how it is laid out in memory.
+ *
+ * The message will have a fixed size, as returned by upb_msg_sizeof(), which
+ * will be used to store fixed-length fields.  The upb_msg may also allocate
+ * dynamic memory internally to store data such as:
+ *
+ * - extensions
+ * - unknown fields
+ */
 
-/* Creates a new message of the given type/layout in this arena. */
-upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a);
+/* Returns the size of a message given this layout. */
+size_t upb_msg_sizeof(const upb_msglayout *l);
 
-/* Returns the arena for the given message. */
-upb_arena *upb_msg_arena(const upb_msg *msg);
+/* upb_msg_init() / upb_msg_uninit() allow the user to use a pre-allocated
+ * block of memory as a message.  The block's size should be upb_msg_sizeof().
+ * upb_msg_uninit() must be called to release internally-allocated memory
+ * unless the allocator is an arena that does not require freeing.
+ *
+ * Please note that upb_msg_init() may return a value that is different than
+ * |msg|, so you must assign the return value and not cast your memory block
+ * to upb_msg* directly!
+ *
+ * Please note that upb_msg_uninit() does *not* free any submessages, maps,
+ * or arrays referred to by this message's fields.  You must free them manually
+ * yourself.
+ *
+ * upb_msg_uninit returns the original memory block, which may be useful if
+ * you dynamically allocated it (though upb_msg_new() would normally be more
+ * appropriate in this case). */
+upb_msg *upb_msg_init(void *msg, const upb_msglayout *l, upb_alloc *a);
+void *upb_msg_uninit(upb_msg *msg, const upb_msglayout *l);
 
-void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len);
-const char *upb_msg_getunknown(const upb_msg *msg, size_t *len);
+/* Like upb_msg_init() / upb_msg_uninit(), except the message's memory is
+ * allocated / freed from the given upb_alloc. */
+upb_msg *upb_msg_new(const upb_msglayout *l, upb_alloc *a);
+void upb_msg_free(upb_msg *msg, const upb_msglayout *l);
+
+/* Returns the upb_alloc for the given message.
+ * TODO(haberman): get rid of this?  Not sure we want to be storing this
+ * for every message. */
+upb_alloc *upb_msg_alloc(const upb_msg *msg);
+
+/* Packs the tree of messages rooted at "msg" into a single hunk of memory,
+ * allocated from the given allocator. */
+void *upb_msg_pack(const upb_msg *msg, const upb_msglayout *l,
+                   void *p, size_t *ofs, size_t size);
 
 /* Read-only message API.  Can be safely called by anyone. */
 
@@ -6650,12 +6627,16 @@
  * semantics are the same as upb_msg.  A upb_array allocates dynamic
  * memory internally for the array elements. */
 
-upb_array *upb_array_new(upb_fieldtype_t type, upb_arena *a);
-upb_fieldtype_t upb_array_type(const upb_array *arr);
+size_t upb_array_sizeof(upb_fieldtype_t type);
+void upb_array_init(upb_array *arr, upb_fieldtype_t type, upb_alloc *a);
+void upb_array_uninit(upb_array *arr);
+upb_array *upb_array_new(upb_fieldtype_t type, upb_alloc *a);
+void upb_array_free(upb_array *arr);
 
 /* Read-only interface.  Safe for anyone to call. */
 
 size_t upb_array_size(const upb_array *arr);
+upb_fieldtype_t upb_array_type(const upb_array *arr);
 upb_msgval upb_array_get(const upb_array *arr, size_t i);
 
 /* Write interface.  May only be called by the message's owner who can enforce
@@ -6672,8 +6653,12 @@
  * So you must ensure that any string or message values outlive the map, and you
  * must delete them manually when they are no longer required. */
 
-upb_map *upb_map_new(upb_fieldtype_t ktype, upb_fieldtype_t vtype,
-                     upb_arena *a);
+size_t upb_map_sizeof(upb_fieldtype_t ktype, upb_fieldtype_t vtype);
+bool upb_map_init(upb_map *map, upb_fieldtype_t ktype, upb_fieldtype_t vtype,
+                  upb_alloc *a);
+void upb_map_uninit(upb_map *map);
+upb_map *upb_map_new(upb_fieldtype_t ktype, upb_fieldtype_t vtype, upb_alloc *a);
+void upb_map_free(upb_map *map);
 
 /* Read-only interface.  Safe for anyone to call. */
 
@@ -6717,870 +6702,91 @@
 void upb_mapiter_setdone(upb_mapiter *i);
 bool upb_mapiter_isequal(const upb_mapiter *i1, const upb_mapiter *i2);
 
+
+/** Handlers ******************************************************************/
+
+/* These are the handlers used internally by upb_msgfactory_getmergehandlers().
+ * They write scalar data to a known offset from the message pointer.
+ *
+ * These would be trivial for anyone to implement themselves, but it's better
+ * to use these because some JITs will recognize and specialize these instead
+ * of actually calling the function. */
+
+/* Sets a handler for the given primitive field that will write the data at the
+ * given offset.  If hasbit > 0, also sets a hasbit at the given bit offset
+ * (addressing each byte low to high). */
+bool upb_msg_setscalarhandler(upb_handlers *h,
+                              const upb_fielddef *f,
+                              size_t offset,
+                              int32_t hasbit);
+
+/* If the given handler is a msghandlers_primitive field, returns true and sets
+ * *type, *offset and *hasbit.  Otherwise returns false. */
+bool upb_msg_getscalarhandlerdata(const upb_handlers *h,
+                                  upb_selector_t s,
+                                  upb_fieldtype_t *type,
+                                  size_t *offset,
+                                  int32_t *hasbit);
+
+
+/** Interfaces for generated code *********************************************/
+
+#define UPB_NOT_IN_ONEOF UINT16_MAX
+#define UPB_NO_HASBIT UINT16_MAX
+#define UPB_NO_SUBMSG UINT16_MAX
+
+typedef struct {
+  uint32_t number;
+  uint32_t offset;  /* If in a oneof, offset of default in default_msg below. */
+  uint16_t hasbit;        /* UPB_NO_HASBIT if no hasbit. */
+  uint16_t oneof_index;   /* UPB_NOT_IN_ONEOF if not in a oneof. */
+  uint16_t submsg_index;  /* UPB_NO_SUBMSG if no submsg. */
+  uint8_t type;
+  uint8_t label;
+} upb_msglayout_fieldinit_v1;
+
+typedef struct {
+  uint32_t data_offset;
+  uint32_t case_offset;
+} upb_msglayout_oneofinit_v1;
+
+typedef struct upb_msglayout_msginit_v1 {
+  const struct upb_msglayout_msginit_v1 *const* submsgs;
+  const upb_msglayout_fieldinit_v1 *fields;
+  const upb_msglayout_oneofinit_v1 *oneofs;
+  void *default_msg;
+  /* Must be aligned to sizeof(void*).  Doesn't include internal members like
+   * unknown fields, extension dict, pointer to msglayout, etc. */
+  uint32_t size;
+  uint16_t field_count;
+  uint16_t oneof_count;
+  bool extendable;
+  bool is_proto2;
+} upb_msglayout_msginit_v1;
+
+#define UPB_ALIGN_UP_TO(val, align) ((val + (align - 1)) & -align)
+#define UPB_ALIGNED_SIZEOF(type) UPB_ALIGN_UP_TO(sizeof(type), sizeof(void*))
+
+/* Initialize/uninitialize a msglayout from a msginit.  If upb uses v1
+ * internally, this will not allocate any memory.  Should only be used by
+ * generated code. */
+upb_msglayout *upb_msglayout_frominit_v1(
+    const upb_msglayout_msginit_v1 *init, upb_alloc *a);
+void upb_msglayout_uninit_v1(upb_msglayout *layout, upb_alloc *a);
+
 UPB_END_EXTERN_C
 
 #endif /* UPB_MSG_H_ */
-/* This file was generated by upbc (the upb compiler) from the input
- * file:
- *
- *     google/protobuf/descriptor.proto
- *
- * Do not edit -- your changes will be discarded when the file is
- * regenerated. */
-
-#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_
-#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_
-
-
-/*
-** upb_decode: parsing into a upb_msg using a upb_msglayout.
-*/
-
-#ifndef UPB_DECODE_H_
-#define UPB_DECODE_H_
-
 
 UPB_BEGIN_EXTERN_C
 
-bool upb_decode(upb_stringview buf, upb_msg *msg, const upb_msglayout *l);
+bool upb_decode(upb_stringview buf, void *msg,
+                const upb_msglayout_msginit_v1 *l, upb_env *env);
 
 UPB_END_EXTERN_C
 
 #endif  /* UPB_DECODE_H_ */
 /*
-** upb_encode: parsing into a upb_msg using a upb_msglayout.
-*/
-
-#ifndef UPB_ENCODE_H_
-#define UPB_ENCODE_H_
-
-
-UPB_BEGIN_EXTERN_C
-
-char *upb_encode(const void *msg, const upb_msglayout *l, upb_arena *arena,
-                 size_t *size);
-
-UPB_END_EXTERN_C
-
-#endif  /* UPB_ENCODE_H_ */
-UPB_BEGIN_EXTERN_C
-
-struct google_protobuf_FileDescriptorSet;
-struct google_protobuf_FileDescriptorProto;
-struct google_protobuf_DescriptorProto;
-struct google_protobuf_DescriptorProto_ExtensionRange;
-struct google_protobuf_DescriptorProto_ReservedRange;
-struct google_protobuf_ExtensionRangeOptions;
-struct google_protobuf_FieldDescriptorProto;
-struct google_protobuf_OneofDescriptorProto;
-struct google_protobuf_EnumDescriptorProto;
-struct google_protobuf_EnumDescriptorProto_EnumReservedRange;
-struct google_protobuf_EnumValueDescriptorProto;
-struct google_protobuf_ServiceDescriptorProto;
-struct google_protobuf_MethodDescriptorProto;
-struct google_protobuf_FileOptions;
-struct google_protobuf_MessageOptions;
-struct google_protobuf_FieldOptions;
-struct google_protobuf_OneofOptions;
-struct google_protobuf_EnumOptions;
-struct google_protobuf_EnumValueOptions;
-struct google_protobuf_ServiceOptions;
-struct google_protobuf_MethodOptions;
-struct google_protobuf_UninterpretedOption;
-struct google_protobuf_UninterpretedOption_NamePart;
-struct google_protobuf_SourceCodeInfo;
-struct google_protobuf_SourceCodeInfo_Location;
-struct google_protobuf_GeneratedCodeInfo;
-struct google_protobuf_GeneratedCodeInfo_Annotation;
-typedef struct google_protobuf_FileDescriptorSet google_protobuf_FileDescriptorSet;
-typedef struct google_protobuf_FileDescriptorProto google_protobuf_FileDescriptorProto;
-typedef struct google_protobuf_DescriptorProto google_protobuf_DescriptorProto;
-typedef struct google_protobuf_DescriptorProto_ExtensionRange google_protobuf_DescriptorProto_ExtensionRange;
-typedef struct google_protobuf_DescriptorProto_ReservedRange google_protobuf_DescriptorProto_ReservedRange;
-typedef struct google_protobuf_ExtensionRangeOptions google_protobuf_ExtensionRangeOptions;
-typedef struct google_protobuf_FieldDescriptorProto google_protobuf_FieldDescriptorProto;
-typedef struct google_protobuf_OneofDescriptorProto google_protobuf_OneofDescriptorProto;
-typedef struct google_protobuf_EnumDescriptorProto google_protobuf_EnumDescriptorProto;
-typedef struct google_protobuf_EnumDescriptorProto_EnumReservedRange google_protobuf_EnumDescriptorProto_EnumReservedRange;
-typedef struct google_protobuf_EnumValueDescriptorProto google_protobuf_EnumValueDescriptorProto;
-typedef struct google_protobuf_ServiceDescriptorProto google_protobuf_ServiceDescriptorProto;
-typedef struct google_protobuf_MethodDescriptorProto google_protobuf_MethodDescriptorProto;
-typedef struct google_protobuf_FileOptions google_protobuf_FileOptions;
-typedef struct google_protobuf_MessageOptions google_protobuf_MessageOptions;
-typedef struct google_protobuf_FieldOptions google_protobuf_FieldOptions;
-typedef struct google_protobuf_OneofOptions google_protobuf_OneofOptions;
-typedef struct google_protobuf_EnumOptions google_protobuf_EnumOptions;
-typedef struct google_protobuf_EnumValueOptions google_protobuf_EnumValueOptions;
-typedef struct google_protobuf_ServiceOptions google_protobuf_ServiceOptions;
-typedef struct google_protobuf_MethodOptions google_protobuf_MethodOptions;
-typedef struct google_protobuf_UninterpretedOption google_protobuf_UninterpretedOption;
-typedef struct google_protobuf_UninterpretedOption_NamePart google_protobuf_UninterpretedOption_NamePart;
-typedef struct google_protobuf_SourceCodeInfo google_protobuf_SourceCodeInfo;
-typedef struct google_protobuf_SourceCodeInfo_Location google_protobuf_SourceCodeInfo_Location;
-typedef struct google_protobuf_GeneratedCodeInfo google_protobuf_GeneratedCodeInfo;
-typedef struct google_protobuf_GeneratedCodeInfo_Annotation google_protobuf_GeneratedCodeInfo_Annotation;
-
-/* Enums */
-
-typedef enum {
-  google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1,
-  google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2,
-  google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3
-} google_protobuf_FieldDescriptorProto_Label;
-
-typedef enum {
-  google_protobuf_FieldDescriptorProto_TYPE_DOUBLE = 1,
-  google_protobuf_FieldDescriptorProto_TYPE_FLOAT = 2,
-  google_protobuf_FieldDescriptorProto_TYPE_INT64 = 3,
-  google_protobuf_FieldDescriptorProto_TYPE_UINT64 = 4,
-  google_protobuf_FieldDescriptorProto_TYPE_INT32 = 5,
-  google_protobuf_FieldDescriptorProto_TYPE_FIXED64 = 6,
-  google_protobuf_FieldDescriptorProto_TYPE_FIXED32 = 7,
-  google_protobuf_FieldDescriptorProto_TYPE_BOOL = 8,
-  google_protobuf_FieldDescriptorProto_TYPE_STRING = 9,
-  google_protobuf_FieldDescriptorProto_TYPE_GROUP = 10,
-  google_protobuf_FieldDescriptorProto_TYPE_MESSAGE = 11,
-  google_protobuf_FieldDescriptorProto_TYPE_BYTES = 12,
-  google_protobuf_FieldDescriptorProto_TYPE_UINT32 = 13,
-  google_protobuf_FieldDescriptorProto_TYPE_ENUM = 14,
-  google_protobuf_FieldDescriptorProto_TYPE_SFIXED32 = 15,
-  google_protobuf_FieldDescriptorProto_TYPE_SFIXED64 = 16,
-  google_protobuf_FieldDescriptorProto_TYPE_SINT32 = 17,
-  google_protobuf_FieldDescriptorProto_TYPE_SINT64 = 18
-} google_protobuf_FieldDescriptorProto_Type;
-
-typedef enum {
-  google_protobuf_FieldOptions_STRING = 0,
-  google_protobuf_FieldOptions_CORD = 1,
-  google_protobuf_FieldOptions_STRING_PIECE = 2
-} google_protobuf_FieldOptions_CType;
-
-typedef enum {
-  google_protobuf_FieldOptions_JS_NORMAL = 0,
-  google_protobuf_FieldOptions_JS_STRING = 1,
-  google_protobuf_FieldOptions_JS_NUMBER = 2
-} google_protobuf_FieldOptions_JSType;
-
-typedef enum {
-  google_protobuf_FileOptions_SPEED = 1,
-  google_protobuf_FileOptions_CODE_SIZE = 2,
-  google_protobuf_FileOptions_LITE_RUNTIME = 3
-} google_protobuf_FileOptions_OptimizeMode;
-
-typedef enum {
-  google_protobuf_MethodOptions_IDEMPOTENCY_UNKNOWN = 0,
-  google_protobuf_MethodOptions_NO_SIDE_EFFECTS = 1,
-  google_protobuf_MethodOptions_IDEMPOTENT = 2
-} google_protobuf_MethodOptions_IdempotencyLevel;
-
-/* google.protobuf.FileDescriptorSet */
-
-extern const upb_msglayout google_protobuf_FileDescriptorSet_msginit;
-UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_FileDescriptorSet_msginit, arena);
-}
-UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_FileDescriptorSet_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_FileDescriptorSet_serialize(const google_protobuf_FileDescriptorSet *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_FileDescriptorSet_msginit, arena, len);
-}
-
-UPB_INLINE const upb_array* google_protobuf_FileDescriptorSet_file(const google_protobuf_FileDescriptorSet *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); }
-
-UPB_INLINE void google_protobuf_FileDescriptorSet_set_file(google_protobuf_FileDescriptorSet *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; }
-
-
-/* google.protobuf.FileDescriptorProto */
-
-extern const upb_msglayout google_protobuf_FileDescriptorProto_msginit;
-UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena);
-}
-UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_FileDescriptorProto_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_FileDescriptorProto_serialize(const google_protobuf_FileDescriptorProto *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_FileDescriptorProto_msginit, arena, len);
-}
-
-UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); }
-UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); }
-UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_dependency(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(40, 80)); }
-UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_message_type(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(44, 88)); }
-UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_enum_type(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(48, 96)); }
-UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_service(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(52, 104)); }
-UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(56, 112)); }
-UPB_INLINE const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_FileOptions*, UPB_SIZE(32, 64)); }
-UPB_INLINE const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_SourceCodeInfo*, UPB_SIZE(36, 72)); }
-UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_public_dependency(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(60, 120)); }
-UPB_INLINE const upb_array* google_protobuf_FileDescriptorProto_weak_dependency(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(64, 128)); }
-UPB_INLINE upb_stringview google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)); }
-
-UPB_INLINE void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; }
-UPB_INLINE void google_protobuf_FileDescriptorProto_set_package(google_protobuf_FileDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; }
-UPB_INLINE void google_protobuf_FileDescriptorProto_set_dependency(google_protobuf_FileDescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(40, 80)) = value; }
-UPB_INLINE void google_protobuf_FileDescriptorProto_set_message_type(google_protobuf_FileDescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(44, 88)) = value; }
-UPB_INLINE void google_protobuf_FileDescriptorProto_set_enum_type(google_protobuf_FileDescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(48, 96)) = value; }
-UPB_INLINE void google_protobuf_FileDescriptorProto_set_service(google_protobuf_FileDescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(52, 104)) = value; }
-UPB_INLINE void google_protobuf_FileDescriptorProto_set_extension(google_protobuf_FileDescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(56, 112)) = value; }
-UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_FileDescriptorProto *msg, google_protobuf_FileOptions* value) { UPB_FIELD_AT(msg, google_protobuf_FileOptions*, UPB_SIZE(32, 64)) = value; }
-UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info(google_protobuf_FileDescriptorProto *msg, google_protobuf_SourceCodeInfo* value) { UPB_FIELD_AT(msg, google_protobuf_SourceCodeInfo*, UPB_SIZE(36, 72)) = value; }
-UPB_INLINE void google_protobuf_FileDescriptorProto_set_public_dependency(google_protobuf_FileDescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(60, 120)) = value; }
-UPB_INLINE void google_protobuf_FileDescriptorProto_set_weak_dependency(google_protobuf_FileDescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(64, 128)) = value; }
-UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)) = value; }
-
-
-/* google.protobuf.DescriptorProto */
-
-extern const upb_msglayout google_protobuf_DescriptorProto_msginit;
-UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
-}
-UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_DescriptorProto_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_DescriptorProto_serialize(const google_protobuf_DescriptorProto *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_DescriptorProto_msginit, arena, len);
-}
-
-UPB_INLINE upb_stringview google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); }
-UPB_INLINE const upb_array* google_protobuf_DescriptorProto_field(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); }
-UPB_INLINE const upb_array* google_protobuf_DescriptorProto_nested_type(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); }
-UPB_INLINE const upb_array* google_protobuf_DescriptorProto_enum_type(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); }
-UPB_INLINE const upb_array* google_protobuf_DescriptorProto_extension_range(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(32, 64)); }
-UPB_INLINE const upb_array* google_protobuf_DescriptorProto_extension(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(36, 72)); }
-UPB_INLINE const google_protobuf_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_MessageOptions*, UPB_SIZE(16, 32)); }
-UPB_INLINE const upb_array* google_protobuf_DescriptorProto_oneof_decl(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(40, 80)); }
-UPB_INLINE const upb_array* google_protobuf_DescriptorProto_reserved_range(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(44, 88)); }
-UPB_INLINE const upb_array* google_protobuf_DescriptorProto_reserved_name(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(48, 96)); }
-
-UPB_INLINE void google_protobuf_DescriptorProto_set_name(google_protobuf_DescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; }
-UPB_INLINE void google_protobuf_DescriptorProto_set_field(google_protobuf_DescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; }
-UPB_INLINE void google_protobuf_DescriptorProto_set_nested_type(google_protobuf_DescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; }
-UPB_INLINE void google_protobuf_DescriptorProto_set_enum_type(google_protobuf_DescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; }
-UPB_INLINE void google_protobuf_DescriptorProto_set_extension_range(google_protobuf_DescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(32, 64)) = value; }
-UPB_INLINE void google_protobuf_DescriptorProto_set_extension(google_protobuf_DescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(36, 72)) = value; }
-UPB_INLINE void google_protobuf_DescriptorProto_set_options(google_protobuf_DescriptorProto *msg, google_protobuf_MessageOptions* value) { UPB_FIELD_AT(msg, google_protobuf_MessageOptions*, UPB_SIZE(16, 32)) = value; }
-UPB_INLINE void google_protobuf_DescriptorProto_set_oneof_decl(google_protobuf_DescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(40, 80)) = value; }
-UPB_INLINE void google_protobuf_DescriptorProto_set_reserved_range(google_protobuf_DescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(44, 88)) = value; }
-UPB_INLINE void google_protobuf_DescriptorProto_set_reserved_name(google_protobuf_DescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(48, 96)) = value; }
-
-
-/* google.protobuf.DescriptorProto.ExtensionRange */
-
-extern const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit;
-UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena);
-}
-UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_DescriptorProto_ExtensionRange_serialize(const google_protobuf_DescriptorProto_ExtensionRange *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, len);
-}
-
-UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); }
-UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
-UPB_INLINE const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, const google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)); }
-
-UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_start(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; }
-UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_end(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; }
-UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_options(google_protobuf_DescriptorProto_ExtensionRange *msg, google_protobuf_ExtensionRangeOptions* value) { UPB_FIELD_AT(msg, google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)) = value; }
-
-
-/* google.protobuf.DescriptorProto.ReservedRange */
-
-extern const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit;
-UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena);
-}
-UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_DescriptorProto_ReservedRange_serialize(const google_protobuf_DescriptorProto_ReservedRange *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena, len);
-}
-
-UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); }
-UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
-
-UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_start(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; }
-UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_end(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; }
-
-
-/* google.protobuf.ExtensionRangeOptions */
-
-extern const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit;
-UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena);
-}
-UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_ExtensionRangeOptions_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_ExtensionRangeOptions_serialize(const google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, arena, len);
-}
-
-UPB_INLINE const upb_array* google_protobuf_ExtensionRangeOptions_uninterpreted_option(const google_protobuf_ExtensionRangeOptions *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); }
-
-UPB_INLINE void google_protobuf_ExtensionRangeOptions_set_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; }
-
-
-/* google.protobuf.FieldDescriptorProto */
-
-extern const upb_msglayout google_protobuf_FieldDescriptorProto_msginit;
-UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
-}
-UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_FieldDescriptorProto_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_FieldDescriptorProto_serialize(const google_protobuf_FieldDescriptorProto *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, arena, len);
-}
-
-UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); }
-UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); }
-UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)); }
-UPB_INLINE google_protobuf_FieldDescriptorProto_Label google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Label, UPB_SIZE(8, 8)); }
-UPB_INLINE google_protobuf_FieldDescriptorProto_Type google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Type, UPB_SIZE(16, 16)); }
-UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); }
-UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)); }
-UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_FieldOptions*, UPB_SIZE(72, 112)); }
-UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)); }
-UPB_INLINE upb_stringview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)); }
-
-UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; }
-UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; }
-UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)) = value; }
-UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldDescriptorProto_Label value) { UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Label, UPB_SIZE(8, 8)) = value; }
-UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldDescriptorProto_Type value) { UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Type, UPB_SIZE(16, 16)) = value; }
-UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; }
-UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)) = value; }
-UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) { UPB_FIELD_AT(msg, google_protobuf_FieldOptions*, UPB_SIZE(72, 112)) = value; }
-UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index(google_protobuf_FieldDescriptorProto *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)) = value; }
-UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)) = value; }
-
-
-/* google.protobuf.OneofDescriptorProto */
-
-extern const upb_msglayout google_protobuf_OneofDescriptorProto_msginit;
-UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena);
-}
-UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_OneofDescriptorProto_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_OneofDescriptorProto_serialize(const google_protobuf_OneofDescriptorProto *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_OneofDescriptorProto_msginit, arena, len);
-}
-
-UPB_INLINE upb_stringview google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); }
-UPB_INLINE const google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_options(const google_protobuf_OneofDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_OneofOptions*, UPB_SIZE(16, 32)); }
-
-UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name(google_protobuf_OneofDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; }
-UPB_INLINE void google_protobuf_OneofDescriptorProto_set_options(google_protobuf_OneofDescriptorProto *msg, google_protobuf_OneofOptions* value) { UPB_FIELD_AT(msg, google_protobuf_OneofOptions*, UPB_SIZE(16, 32)) = value; }
-
-
-/* google.protobuf.EnumDescriptorProto */
-
-extern const upb_msglayout google_protobuf_EnumDescriptorProto_msginit;
-UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
-}
-UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_EnumDescriptorProto_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_EnumDescriptorProto_serialize(const google_protobuf_EnumDescriptorProto *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_EnumDescriptorProto_msginit, arena, len);
-}
-
-UPB_INLINE upb_stringview google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); }
-UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_value(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); }
-UPB_INLINE const google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_options(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_EnumOptions*, UPB_SIZE(16, 32)); }
-UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_reserved_range(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); }
-UPB_INLINE const upb_array* google_protobuf_EnumDescriptorProto_reserved_name(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); }
-
-UPB_INLINE void google_protobuf_EnumDescriptorProto_set_name(google_protobuf_EnumDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; }
-UPB_INLINE void google_protobuf_EnumDescriptorProto_set_value(google_protobuf_EnumDescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; }
-UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options(google_protobuf_EnumDescriptorProto *msg, google_protobuf_EnumOptions* value) { UPB_FIELD_AT(msg, google_protobuf_EnumOptions*, UPB_SIZE(16, 32)) = value; }
-UPB_INLINE void google_protobuf_EnumDescriptorProto_set_reserved_range(google_protobuf_EnumDescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; }
-UPB_INLINE void google_protobuf_EnumDescriptorProto_set_reserved_name(google_protobuf_EnumDescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; }
-
-
-/* google.protobuf.EnumDescriptorProto.EnumReservedRange */
-
-extern const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit;
-UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena);
-}
-UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena, len);
-}
-
-UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); }
-UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
-
-UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; }
-UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; }
-
-
-/* google.protobuf.EnumValueDescriptorProto */
-
-extern const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit;
-UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena);
-}
-UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_EnumValueDescriptorProto_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_EnumValueDescriptorProto_serialize(const google_protobuf_EnumValueDescriptorProto *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_EnumValueDescriptorProto_msginit, arena, len);
-}
-
-UPB_INLINE upb_stringview google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); }
-UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); }
-UPB_INLINE const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_EnumValueOptions*, UPB_SIZE(16, 32)); }
-
-UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; }
-UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number(google_protobuf_EnumValueDescriptorProto *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; }
-UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options(google_protobuf_EnumValueDescriptorProto *msg, google_protobuf_EnumValueOptions* value) { UPB_FIELD_AT(msg, google_protobuf_EnumValueOptions*, UPB_SIZE(16, 32)) = value; }
-
-
-/* google.protobuf.ServiceDescriptorProto */
-
-extern const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit;
-UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena);
-}
-UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_ServiceDescriptorProto_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_ServiceDescriptorProto_serialize(const google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_ServiceDescriptorProto_msginit, arena, len);
-}
-
-UPB_INLINE upb_stringview google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); }
-UPB_INLINE const upb_array* google_protobuf_ServiceDescriptorProto_method(const google_protobuf_ServiceDescriptorProto *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 40)); }
-UPB_INLINE const google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_options(const google_protobuf_ServiceDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_ServiceOptions*, UPB_SIZE(16, 32)); }
-
-UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name(google_protobuf_ServiceDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; }
-UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_method(google_protobuf_ServiceDescriptorProto *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 40)) = value; }
-UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options(google_protobuf_ServiceDescriptorProto *msg, google_protobuf_ServiceOptions* value) { UPB_FIELD_AT(msg, google_protobuf_ServiceOptions*, UPB_SIZE(16, 32)) = value; }
-
-
-/* google.protobuf.MethodDescriptorProto */
-
-extern const upb_msglayout google_protobuf_MethodDescriptorProto_msginit;
-UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena);
-}
-UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_MethodDescriptorProto_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_MethodDescriptorProto_serialize(const google_protobuf_MethodDescriptorProto *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_MethodDescriptorProto_msginit, arena, len);
-}
-
-UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); }
-UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); }
-UPB_INLINE upb_stringview google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)); }
-UPB_INLINE const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_MethodOptions*, UPB_SIZE(32, 64)); }
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); }
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); }
-
-UPB_INLINE void google_protobuf_MethodDescriptorProto_set_name(google_protobuf_MethodDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; }
-UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type(google_protobuf_MethodDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; }
-UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type(google_protobuf_MethodDescriptorProto *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(24, 48)) = value; }
-UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options(google_protobuf_MethodDescriptorProto *msg, google_protobuf_MethodOptions* value) { UPB_FIELD_AT(msg, google_protobuf_MethodOptions*, UPB_SIZE(32, 64)) = value; }
-UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; }
-UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; }
-
-
-/* google.protobuf.FileOptions */
-
-extern const upb_msglayout google_protobuf_FileOptions_msginit;
-UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_FileOptions_msginit, arena);
-}
-UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_FileOptions_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_FileOptions_serialize(const google_protobuf_FileOptions *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_FileOptions_msginit, arena, len);
-}
-
-UPB_INLINE upb_stringview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); }
-UPB_INLINE upb_stringview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); }
-UPB_INLINE google_protobuf_FileOptions_OptimizeMode google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_FileOptions_OptimizeMode, UPB_SIZE(8, 8)); }
-UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); }
-UPB_INLINE upb_stringview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); }
-UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)); }
-UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)); }
-UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)); }
-UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)); }
-UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)); }
-UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)); }
-UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)); }
-UPB_INLINE upb_stringview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)); }
-UPB_INLINE upb_stringview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)); }
-UPB_INLINE upb_stringview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(72, 112)); }
-UPB_INLINE upb_stringview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(80, 128)); }
-UPB_INLINE upb_stringview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(88, 144)); }
-UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); }
-UPB_INLINE const upb_array* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(96, 160)); }
-
-UPB_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, google_protobuf_FileOptions_OptimizeMode value) { UPB_FIELD_AT(msg, google_protobuf_FileOptions_OptimizeMode, UPB_SIZE(8, 8)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services(google_protobuf_FileOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services(google_protobuf_FileOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_java_generate_equals_and_hash(google_protobuf_FileOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_deprecated(google_protobuf_FileOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8(google_protobuf_FileOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf_FileOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(56, 80)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(64, 96)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(72, 112)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(80, 128)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(88, 144)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services(google_protobuf_FileOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; }
-UPB_INLINE void google_protobuf_FileOptions_set_uninterpreted_option(google_protobuf_FileOptions *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(96, 160)) = value; }
-
-
-/* google.protobuf.MessageOptions */
-
-extern const upb_msglayout google_protobuf_MessageOptions_msginit;
-UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_MessageOptions_msginit, arena);
-}
-UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_MessageOptions_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_MessageOptions_serialize(const google_protobuf_MessageOptions *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_MessageOptions_msginit, arena, len);
-}
-
-UPB_INLINE bool google_protobuf_MessageOptions_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); }
-UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); }
-UPB_INLINE bool google_protobuf_MessageOptions_deprecated(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)); }
-UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)); }
-UPB_INLINE const upb_array* google_protobuf_MessageOptions_uninterpreted_option(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(8, 8)); }
-
-UPB_INLINE void google_protobuf_MessageOptions_set_message_set_wire_format(google_protobuf_MessageOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; }
-UPB_INLINE void google_protobuf_MessageOptions_set_no_standard_descriptor_accessor(google_protobuf_MessageOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; }
-UPB_INLINE void google_protobuf_MessageOptions_set_deprecated(google_protobuf_MessageOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)) = value; }
-UPB_INLINE void google_protobuf_MessageOptions_set_map_entry(google_protobuf_MessageOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)) = value; }
-UPB_INLINE void google_protobuf_MessageOptions_set_uninterpreted_option(google_protobuf_MessageOptions *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(8, 8)) = value; }
-
-
-/* google.protobuf.FieldOptions */
-
-extern const upb_msglayout google_protobuf_FieldOptions_msginit;
-UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_FieldOptions_msginit, arena);
-}
-UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_FieldOptions_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_FieldOptions_serialize(const google_protobuf_FieldOptions *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_FieldOptions_msginit, arena, len);
-}
-
-UPB_INLINE google_protobuf_FieldOptions_CType google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldOptions_CType, UPB_SIZE(8, 8)); }
-UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); }
-UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)); }
-UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)); }
-UPB_INLINE google_protobuf_FieldOptions_JSType google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldOptions_JSType, UPB_SIZE(16, 16)); }
-UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)); }
-UPB_INLINE const upb_array* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 32)); }
-
-UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, google_protobuf_FieldOptions_CType value) { UPB_FIELD_AT(msg, google_protobuf_FieldOptions_CType, UPB_SIZE(8, 8)) = value; }
-UPB_INLINE void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; }
-UPB_INLINE void google_protobuf_FieldOptions_set_deprecated(google_protobuf_FieldOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)) = value; }
-UPB_INLINE void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)) = value; }
-UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions *msg, google_protobuf_FieldOptions_JSType value) { UPB_FIELD_AT(msg, google_protobuf_FieldOptions_JSType, UPB_SIZE(16, 16)) = value; }
-UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)) = value; }
-UPB_INLINE void google_protobuf_FieldOptions_set_uninterpreted_option(google_protobuf_FieldOptions *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 32)) = value; }
-
-
-/* google.protobuf.OneofOptions */
-
-extern const upb_msglayout google_protobuf_OneofOptions_msginit;
-UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_OneofOptions_msginit, arena);
-}
-UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_OneofOptions_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_OneofOptions_serialize(const google_protobuf_OneofOptions *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_OneofOptions_msginit, arena, len);
-}
-
-UPB_INLINE const upb_array* google_protobuf_OneofOptions_uninterpreted_option(const google_protobuf_OneofOptions *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); }
-
-UPB_INLINE void google_protobuf_OneofOptions_set_uninterpreted_option(google_protobuf_OneofOptions *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; }
-
-
-/* google.protobuf.EnumOptions */
-
-extern const upb_msglayout google_protobuf_EnumOptions_msginit;
-UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_EnumOptions_msginit, arena);
-}
-UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_EnumOptions_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_EnumOptions_serialize(const google_protobuf_EnumOptions *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_EnumOptions_msginit, arena, len);
-}
-
-UPB_INLINE bool google_protobuf_EnumOptions_allow_alias(const google_protobuf_EnumOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); }
-UPB_INLINE bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); }
-UPB_INLINE const upb_array* google_protobuf_EnumOptions_uninterpreted_option(const google_protobuf_EnumOptions *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); }
-
-UPB_INLINE void google_protobuf_EnumOptions_set_allow_alias(google_protobuf_EnumOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; }
-UPB_INLINE void google_protobuf_EnumOptions_set_deprecated(google_protobuf_EnumOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; }
-UPB_INLINE void google_protobuf_EnumOptions_set_uninterpreted_option(google_protobuf_EnumOptions *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; }
-
-
-/* google.protobuf.EnumValueOptions */
-
-extern const upb_msglayout google_protobuf_EnumValueOptions_msginit;
-UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena);
-}
-UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_EnumValueOptions_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_EnumValueOptions_serialize(const google_protobuf_EnumValueOptions *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_EnumValueOptions_msginit, arena, len);
-}
-
-UPB_INLINE bool google_protobuf_EnumValueOptions_deprecated(const google_protobuf_EnumValueOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); }
-UPB_INLINE const upb_array* google_protobuf_EnumValueOptions_uninterpreted_option(const google_protobuf_EnumValueOptions *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); }
-
-UPB_INLINE void google_protobuf_EnumValueOptions_set_deprecated(google_protobuf_EnumValueOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; }
-UPB_INLINE void google_protobuf_EnumValueOptions_set_uninterpreted_option(google_protobuf_EnumValueOptions *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; }
-
-
-/* google.protobuf.ServiceOptions */
-
-extern const upb_msglayout google_protobuf_ServiceOptions_msginit;
-UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena);
-}
-UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_ServiceOptions_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_ServiceOptions_serialize(const google_protobuf_ServiceOptions *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_ServiceOptions_msginit, arena, len);
-}
-
-UPB_INLINE bool google_protobuf_ServiceOptions_deprecated(const google_protobuf_ServiceOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); }
-UPB_INLINE const upb_array* google_protobuf_ServiceOptions_uninterpreted_option(const google_protobuf_ServiceOptions *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(4, 8)); }
-
-UPB_INLINE void google_protobuf_ServiceOptions_set_deprecated(google_protobuf_ServiceOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; }
-UPB_INLINE void google_protobuf_ServiceOptions_set_uninterpreted_option(google_protobuf_ServiceOptions *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(4, 8)) = value; }
-
-
-/* google.protobuf.MethodOptions */
-
-extern const upb_msglayout google_protobuf_MethodOptions_msginit;
-UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_MethodOptions_msginit, arena);
-}
-UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_MethodOptions_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_MethodOptions_serialize(const google_protobuf_MethodOptions *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_MethodOptions_msginit, arena, len);
-}
-
-UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); }
-UPB_INLINE google_protobuf_MethodOptions_IdempotencyLevel google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_MethodOptions_IdempotencyLevel, UPB_SIZE(8, 8)); }
-UPB_INLINE const upb_array* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(20, 24)); }
-
-UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; }
-UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions *msg, google_protobuf_MethodOptions_IdempotencyLevel value) { UPB_FIELD_AT(msg, google_protobuf_MethodOptions_IdempotencyLevel, UPB_SIZE(8, 8)) = value; }
-UPB_INLINE void google_protobuf_MethodOptions_set_uninterpreted_option(google_protobuf_MethodOptions *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(20, 24)) = value; }
-
-
-/* google.protobuf.UninterpretedOption */
-
-extern const upb_msglayout google_protobuf_UninterpretedOption_msginit;
-UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-}
-UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_UninterpretedOption_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_UninterpretedOption_serialize(const google_protobuf_UninterpretedOption *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_UninterpretedOption_msginit, arena, len);
-}
-
-UPB_INLINE const upb_array* google_protobuf_UninterpretedOption_name(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(56, 80)); }
-UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)); }
-UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); }
-UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); }
-UPB_INLINE double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)); }
-UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)); }
-UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)); }
-
-UPB_INLINE void google_protobuf_UninterpretedOption_set_name(google_protobuf_UninterpretedOption *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(56, 80)) = value; }
-UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(32, 32)) = value; }
-UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value(google_protobuf_UninterpretedOption *msg, uint64_t value) { UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; }
-UPB_INLINE void google_protobuf_UninterpretedOption_set_negative_int_value(google_protobuf_UninterpretedOption *msg, int64_t value) { UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)) = value; }
-UPB_INLINE void google_protobuf_UninterpretedOption_set_double_value(google_protobuf_UninterpretedOption *msg, double value) { UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)) = value; }
-UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value(google_protobuf_UninterpretedOption *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(40, 48)) = value; }
-UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value(google_protobuf_UninterpretedOption *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(48, 64)) = value; }
-
-
-/* google.protobuf.UninterpretedOption.NamePart */
-
-extern const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit;
-UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena);
-}
-UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_UninterpretedOption_NamePart_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_UninterpretedOption_NamePart_serialize(const google_protobuf_UninterpretedOption_NamePart *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_UninterpretedOption_NamePart_msginit, arena, len);
-}
-
-UPB_INLINE upb_stringview google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); }
-UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); }
-
-UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part(google_protobuf_UninterpretedOption_NamePart *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; }
-UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension(google_protobuf_UninterpretedOption_NamePart *msg, bool value) { UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; }
-
-
-/* google.protobuf.SourceCodeInfo */
-
-extern const upb_msglayout google_protobuf_SourceCodeInfo_msginit;
-UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena);
-}
-UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_SourceCodeInfo_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_SourceCodeInfo_serialize(const google_protobuf_SourceCodeInfo *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_SourceCodeInfo_msginit, arena, len);
-}
-
-UPB_INLINE const upb_array* google_protobuf_SourceCodeInfo_location(const google_protobuf_SourceCodeInfo *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); }
-
-UPB_INLINE void google_protobuf_SourceCodeInfo_set_location(google_protobuf_SourceCodeInfo *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; }
-
-
-/* google.protobuf.SourceCodeInfo.Location */
-
-extern const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit;
-UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena);
-}
-UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_SourceCodeInfo_Location_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_SourceCodeInfo_Location_serialize(const google_protobuf_SourceCodeInfo_Location *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_SourceCodeInfo_Location_msginit, arena, len);
-}
-
-UPB_INLINE const upb_array* google_protobuf_SourceCodeInfo_Location_path(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 48)); }
-UPB_INLINE const upb_array* google_protobuf_SourceCodeInfo_Location_span(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(28, 56)); }
-UPB_INLINE upb_stringview google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)); }
-UPB_INLINE upb_stringview google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)); }
-UPB_INLINE const upb_array* google_protobuf_SourceCodeInfo_Location_leading_detached_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(32, 64)); }
-
-UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_path(google_protobuf_SourceCodeInfo_Location *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 48)) = value; }
-UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_span(google_protobuf_SourceCodeInfo_Location *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(28, 56)) = value; }
-UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(8, 16)) = value; }
-UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 32)) = value; }
-UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(32, 64)) = value; }
-
-
-/* google.protobuf.GeneratedCodeInfo */
-
-extern const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit;
-UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_GeneratedCodeInfo_msginit, arena);
-}
-UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_GeneratedCodeInfo_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_GeneratedCodeInfo_serialize(const google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, arena, len);
-}
-
-UPB_INLINE const upb_array* google_protobuf_GeneratedCodeInfo_annotation(const google_protobuf_GeneratedCodeInfo *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(0, 0)); }
-
-UPB_INLINE void google_protobuf_GeneratedCodeInfo_set_annotation(google_protobuf_GeneratedCodeInfo *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(0, 0)) = value; }
-
-
-/* google.protobuf.GeneratedCodeInfo.Annotation */
-
-extern const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit;
-UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_new(upb_arena *arena) {
-  return upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena);
-}
-UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parsenew(upb_stringview buf, upb_arena *arena) {
-  google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena);
-  return (ret && upb_decode(buf, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit)) ? ret : NULL;
-}
-UPB_INLINE char *google_protobuf_GeneratedCodeInfo_Annotation_serialize(const google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_arena *arena, size_t *len) {
-  return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena, len);
-}
-
-UPB_INLINE const upb_array* google_protobuf_GeneratedCodeInfo_Annotation_path(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, const upb_array*, UPB_SIZE(24, 32)); }
-UPB_INLINE upb_stringview google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 16)); }
-UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); }
-UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
-
-UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_array* value) { UPB_FIELD_AT(msg, upb_array*, UPB_SIZE(24, 32)) = value; }
-UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_stringview value) { UPB_FIELD_AT(msg, upb_stringview, UPB_SIZE(16, 16)) = value; }
-UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; }
-UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) { UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; }
-
-
-UPB_END_EXTERN_C
-
-
-#endif  /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ */
-/*
 ** structs.int.h: structures definitions that are internal to upb.
 */
 
@@ -7593,7 +6799,7 @@
   void *data;   /* Each element is element_size. */
   size_t len;   /* Measured in elements. */
   size_t size;  /* Measured in elements. */
-  upb_arena *arena;
+  upb_alloc *alloc;
 };
 
 #endif  /* UPB_STRUCTS_H_ */
@@ -7714,10 +6920,6 @@
   /* Whether this message has proto2 or proto3 semantics. */
   upb_syntax_t syntax;
 
-  /* Type of well known type message. UPB_WELLKNOWN_UNSPECIFIED for
-   * non-well-known message. */
-  upb_wellknowntype_t well_known_type;
-
   /* TODO(haberman): proper extension ranges (there can be multiple). */
 };
 
@@ -7726,11 +6928,10 @@
 /* TODO: also support static initialization of the oneofs table. This will be
  * needed if we compile in descriptors that contain oneofs. */
 #define UPB_MSGDEF_INIT(name, selector_count, submsg_field_count, itof, ntof, \
-                        map_entry, syntax, well_known_type, refs, ref2s)      \
+                        map_entry, syntax, refs, ref2s)                       \
   {                                                                           \
     UPB_DEF_INIT(name, UPB_DEF_MSG, &upb_fielddef_vtbl, refs, ref2s),         \
-        selector_count, submsg_field_count, itof, ntof, map_entry, syntax,    \
-        well_known_type                                                       \
+        selector_count, submsg_field_count, itof, ntof, map_entry, syntax     \
   }
 
 
@@ -7793,44 +6994,22 @@
 extern const struct upb_refcounted_vtbl upb_filedef_vtbl;
 
 #endif  /* UPB_STATICINIT_H_ */
+/*
+** upb_encode: parsing into a upb_msg using a upb_msglayout.
+*/
+
+#ifndef UPB_ENCODE_H_
+#define UPB_ENCODE_H_
 
 
-#ifndef UPB_MSGFACTORY_H_
-#define UPB_MSGFACTORY_H_
+UPB_BEGIN_EXTERN_C
 
-UPB_DECLARE_TYPE(upb::MessageFactory, upb_msgfactory)
+char *upb_encode(const void *msg, const upb_msglayout_msginit_v1 *l,
+                 upb_env *env, size_t *size);
 
-/** upb_msgfactory ************************************************************/
+UPB_END_EXTERN_C
 
-/* A upb_msgfactory contains a cache of upb_msglayout, upb_handlers, and
- * upb_visitorplan objects.  These are the objects necessary to represent,
- * populate, and and visit upb_msg objects.
- *
- * These caches are all populated by upb_msgdef, and lazily created on demand.
- */
-
-/* Creates and destroys a msgfactory, respectively.  The messages for this
- * msgfactory must come from |symtab| (which should outlive the msgfactory). */
-upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab);
-void upb_msgfactory_free(upb_msgfactory *f);
-
-const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f);
-
-/* The functions to get cached objects, lazily creating them on demand.  These
- * all require:
- *
- * - m is in upb_msgfactory_symtab(f)
- * - upb_msgdef_mapentry(m) == false (since map messages can't have layouts).
- *
- * The returned objects will live for as long as the msgfactory does.
- *
- * TODO(haberman): consider making this thread-safe and take a const
- * upb_msgfactory. */
-const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
-                                              const upb_msgdef *m);
-
-
-#endif /* UPB_MSGFACTORY_H_ */
+#endif  /* UPB_ENCODE_H_ */
 /*
 ** upb::descriptor::Reader (upb_descreader)
 **
@@ -7933,6 +7112,53 @@
 
 UPB_BEGIN_EXTERN_C
 
+/* Enums */
+
+typedef enum {
+  google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1,
+  google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2,
+  google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3
+} google_protobuf_FieldDescriptorProto_Label;
+
+typedef enum {
+  google_protobuf_FieldDescriptorProto_TYPE_DOUBLE = 1,
+  google_protobuf_FieldDescriptorProto_TYPE_FLOAT = 2,
+  google_protobuf_FieldDescriptorProto_TYPE_INT64 = 3,
+  google_protobuf_FieldDescriptorProto_TYPE_UINT64 = 4,
+  google_protobuf_FieldDescriptorProto_TYPE_INT32 = 5,
+  google_protobuf_FieldDescriptorProto_TYPE_FIXED64 = 6,
+  google_protobuf_FieldDescriptorProto_TYPE_FIXED32 = 7,
+  google_protobuf_FieldDescriptorProto_TYPE_BOOL = 8,
+  google_protobuf_FieldDescriptorProto_TYPE_STRING = 9,
+  google_protobuf_FieldDescriptorProto_TYPE_GROUP = 10,
+  google_protobuf_FieldDescriptorProto_TYPE_MESSAGE = 11,
+  google_protobuf_FieldDescriptorProto_TYPE_BYTES = 12,
+  google_protobuf_FieldDescriptorProto_TYPE_UINT32 = 13,
+  google_protobuf_FieldDescriptorProto_TYPE_ENUM = 14,
+  google_protobuf_FieldDescriptorProto_TYPE_SFIXED32 = 15,
+  google_protobuf_FieldDescriptorProto_TYPE_SFIXED64 = 16,
+  google_protobuf_FieldDescriptorProto_TYPE_SINT32 = 17,
+  google_protobuf_FieldDescriptorProto_TYPE_SINT64 = 18
+} google_protobuf_FieldDescriptorProto_Type;
+
+typedef enum {
+  google_protobuf_FieldOptions_STRING = 0,
+  google_protobuf_FieldOptions_CORD = 1,
+  google_protobuf_FieldOptions_STRING_PIECE = 2
+} google_protobuf_FieldOptions_CType;
+
+typedef enum {
+  google_protobuf_FieldOptions_JS_NORMAL = 0,
+  google_protobuf_FieldOptions_JS_STRING = 1,
+  google_protobuf_FieldOptions_JS_NUMBER = 2
+} google_protobuf_FieldOptions_JSType;
+
+typedef enum {
+  google_protobuf_FileOptions_SPEED = 1,
+  google_protobuf_FileOptions_CODE_SIZE = 2,
+  google_protobuf_FileOptions_LITE_RUNTIME = 3
+} google_protobuf_FileOptions_OptimizeMode;
+
 /* MessageDefs: call these functions to get a ref to a msgdef. */
 const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_get(const void *owner);
 const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_get(const void *owner);
@@ -9567,7 +8793,7 @@
  * constructed.  This hint may be an overestimate for some build configurations.
  * But if the parser library is upgraded without recompiling the application,
  * it may be an underestimate. */
-#define UPB_JSON_PARSER_SIZE 4160
+#define UPB_JSON_PARSER_SIZE 4112
 
 #ifdef __cplusplus
 
@@ -9576,7 +8802,7 @@
 class upb::json::Parser {
  public:
   static Parser* Create(Environment* env, const ParserMethod* method,
-                        Sink* output, bool ignore_json_unknown);
+                        Sink* output);
 
   BytesSink* input();
 
@@ -9610,8 +8836,7 @@
 
 upb_json_parser* upb_json_parser_create(upb_env* e,
                                         const upb_json_parsermethod* m,
-                                        upb_sink* output,
-                                        bool ignore_json_unknown);
+                                        upb_sink* output);
 upb_bytessink *upb_json_parser_input(upb_json_parser *p);
 
 upb_json_parsermethod* upb_json_parsermethod_new(const upb_msgdef* md,
@@ -9631,8 +8856,8 @@
 namespace upb {
 namespace json {
 inline Parser* Parser::Create(Environment* env, const ParserMethod* method,
-                              Sink* output, bool ignore_json_unknown) {
-  return upb_json_parser_create(env, method, output, ignore_json_unknown);
+                              Sink* output) {
+  return upb_json_parser_create(env, method, output);
 }
 inline BytesSink* Parser::input() {
   return upb_json_parser_input(this);
@@ -9681,7 +8906,7 @@
 
 /* upb::json::Printer *********************************************************/
 
-#define UPB_JSON_PRINTER_SIZE 192
+#define UPB_JSON_PRINTER_SIZE 176
 
 #ifdef __cplusplus
 
@@ -9742,8 +8967,3 @@
 #endif
 
 #endif  /* UPB_JSON_TYPED_PRINTER_H_ */
-
-#undef UPB_SIZE
-#undef UPB_FIELD_AT
-#undef UPB_READ_ONEOF
-#undef UPB_WRITE_ONEOF
diff --git a/ruby/lib/google/protobuf.rb b/ruby/lib/google/protobuf.rb
index 464982e..e20a584 100644
--- a/ruby/lib/google/protobuf.rb
+++ b/ruby/lib/google/protobuf.rb
@@ -69,8 +69,8 @@
       klass.decode(proto)
     end
 
-    def self.decode_json(klass, json, options = {})
-      klass.decode_json(json, options)
+    def self.decode_json(klass, json)
+      klass.decode_json(json)
     end
 
   end
diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb
index 5e17bef..77dfead 100644
--- a/ruby/tests/basic.rb
+++ b/ruby/tests/basic.rb
@@ -254,19 +254,6 @@
                     "b" => TestMessage2.new(:foo => 2)}
     end
 
-    def test_protobuf_decode_json_ignore_unknown_fields
-      m = TestMessage.decode_json({
-        optional_string: "foo",
-        not_in_message: "some_value"
-      }.to_json, { ignore_unknown_fields: true })
-
-      assert_equal m.optional_string, "foo"
-      e = assert_raise Google::Protobuf::ParseError do
-        TestMessage.decode_json({ not_in_message: "some_value" }.to_json)
-      end
-      assert_match(/No such field: not_in_message/, e.message)
-    end
-
     def test_to_h
       m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'], :repeated_msg => [TestMessage2.new(:foo => 100)])
       expected_result = {